MXS-2349: Add socket parameter

Servers now accept the `socket` parameter in the configuration as well as
in the REST API.
This commit is contained in:
Markus Mäkelä
2019-04-12 12:13:15 +03:00
parent 70450ce881
commit 993334b9fd
4 changed files with 101 additions and 15 deletions

View File

@ -61,6 +61,7 @@ class SERVICE;
/** Parameter value JSON Pointers */ /** Parameter value JSON Pointers */
#define MXS_JSON_PTR_PARAM_PORT MXS_JSON_PTR_PARAMETERS "/port" #define MXS_JSON_PTR_PARAM_PORT MXS_JSON_PTR_PARAMETERS "/port"
#define MXS_JSON_PTR_PARAM_ADDRESS MXS_JSON_PTR_PARAMETERS "/address" #define MXS_JSON_PTR_PARAM_ADDRESS MXS_JSON_PTR_PARAMETERS "/address"
#define MXS_JSON_PTR_PARAM_SOCKET MXS_JSON_PTR_PARAMETERS "/socket"
#define MXS_JSON_PTR_PARAM_PROTOCOL MXS_JSON_PTR_PARAMETERS "/protocol" #define MXS_JSON_PTR_PARAM_PROTOCOL MXS_JSON_PTR_PARAMETERS "/protocol"
#define MXS_JSON_PTR_PARAM_AUTHENTICATOR MXS_JSON_PTR_PARAMETERS "/authenticator" #define MXS_JSON_PTR_PARAM_AUTHENTICATOR MXS_JSON_PTR_PARAMETERS "/authenticator"
#define MXS_JSON_PTR_PARAM_AUTHENTICATOR_OPTIONS MXS_JSON_PTR_PARAMETERS "/authenticator_options" #define MXS_JSON_PTR_PARAM_AUTHENTICATOR_OPTIONS MXS_JSON_PTR_PARAMETERS "/authenticator_options"

View File

@ -592,9 +592,11 @@ const MXS_MODULE_PARAM config_server_params[] =
}, },
{ {
CN_ADDRESS, CN_ADDRESS,
MXS_MODULE_PARAM_STRING, MXS_MODULE_PARAM_STRING
NULL, },
MXS_MODULE_OPT_REQUIRED {
CN_SOCKET,
MXS_MODULE_PARAM_STRING
}, },
{ {
CN_PROTOCOL, CN_PROTOCOL,
@ -3974,6 +3976,27 @@ int create_new_server(CONFIG_CONTEXT* obj)
return 1; return 1;
} }
bool have_address = obj->m_parameters.contains(CN_ADDRESS);
bool have_socket = obj->m_parameters.contains(CN_SOCKET);
if (have_socket && have_address)
{
MXS_ERROR("Both '%s' and '%s' defined for server '%s': only one of the parameters can be defined",
CN_ADDRESS, CN_SOCKET, obj->name());
return 1;
}
else if (!have_address && !have_socket)
{
MXS_ERROR("Server '%s' is missing a required parameter: either '%s' or '%s' must be defined",
obj->name(), CN_ADDRESS, CN_SOCKET);
return 1;
}
else if (have_address && obj->m_parameters.get_string(CN_ADDRESS)[0] == '/')
{
MXS_ERROR("The '%s' parameter for '%s' is not a valid IP or hostname", CN_ADDRESS, obj->name());
return 1;
}
if (Server* server = Server::server_alloc(obj->name(), &obj->m_parameters)) if (Server* server = Server::server_alloc(obj->name(), &obj->m_parameters))
{ {
auto disk_space_threshold = obj->m_parameters.get_string(CN_DISK_SPACE_THRESHOLD); auto disk_space_threshold = obj->m_parameters.get_string(CN_DISK_SPACE_THRESHOLD);

View File

@ -346,7 +346,8 @@ bool runtime_create_server(const char* name,
{ {
if (address) if (address)
{ {
parameters.set(CN_ADDRESS, address); auto param_name = *address == '/' ? CN_SOCKET : CN_ADDRESS;
parameters.set(param_name, address);
} }
if (port) if (port)
{ {
@ -597,7 +598,7 @@ bool runtime_alter_server(Server* server, const char* key, const char* value)
std::lock_guard<std::mutex> guard(crt_lock); std::lock_guard<std::mutex> guard(crt_lock);
server->set_parameter(key, value); server->set_parameter(key, value);
if (strcmp(key, CN_ADDRESS) == 0) if (strcmp(key, CN_ADDRESS) == 0 || strcmp(key, CN_SOCKET) == 0)
{ {
server->server_update_address(value); server->server_update_address(value);
} }
@ -1740,11 +1741,52 @@ static bool is_valid_resource_body(json_t* json)
return rval; return rval;
} }
static bool server_alter_fields_are_valid(json_t* json)
{
bool rval = false;
json_t* address = mxs_json_pointer(json, MXS_JSON_PTR_PARAM_ADDRESS);
json_t* socket = mxs_json_pointer(json, MXS_JSON_PTR_PARAM_SOCKET);
json_t* port = mxs_json_pointer(json, MXS_JSON_PTR_PARAM_PORT);
if (address && socket)
{
config_runtime_error("Request body defines both of the '%s' and '%s' fields",
MXS_JSON_PTR_PARAM_ADDRESS, MXS_JSON_PTR_PARAM_SOCKET);
}
else if (address && !json_is_string(address))
{
config_runtime_error("The '%s' field is not a string", MXS_JSON_PTR_PARAM_ADDRESS);
}
else if (address && json_is_string(address) && json_string_value(address)[0] == '/')
{
config_runtime_error("The '%s' field is not a valid address", MXS_JSON_PTR_PARAM_ADDRESS);
}
else if (socket && !json_is_string(socket))
{
config_runtime_error("The '%s' field is not a string", MXS_JSON_PTR_PARAM_SOCKET);
}
else if (port && !json_is_integer(port))
{
config_runtime_error("The '%s' field is not an integer", MXS_JSON_PTR_PARAM_PORT);
}
else if (socket && !json_is_string(socket))
{
config_runtime_error("The '%s' field is not a string", MXS_JSON_PTR_PARAM_SOCKET);
}
else
{
rval = true;
}
return rval;
}
static bool server_contains_required_fields(json_t* json) static bool server_contains_required_fields(json_t* json)
{ {
json_t* id = mxs_json_pointer(json, MXS_JSON_PTR_ID); json_t* id = mxs_json_pointer(json, MXS_JSON_PTR_ID);
json_t* port = mxs_json_pointer(json, MXS_JSON_PTR_PARAM_PORT); json_t* port = mxs_json_pointer(json, MXS_JSON_PTR_PARAM_PORT);
json_t* address = mxs_json_pointer(json, MXS_JSON_PTR_PARAM_ADDRESS); json_t* address = mxs_json_pointer(json, MXS_JSON_PTR_PARAM_ADDRESS);
json_t* socket = mxs_json_pointer(json, MXS_JSON_PTR_PARAM_SOCKET);
bool rval = false; bool rval = false;
if (!id) if (!id)
@ -1755,19 +1797,33 @@ static bool server_contains_required_fields(json_t* json)
{ {
config_runtime_error("The '%s' field is not a string", MXS_JSON_PTR_ID); config_runtime_error("The '%s' field is not a string", MXS_JSON_PTR_ID);
} }
else if (!address) else if (!address && !socket)
{ {
config_runtime_error("Request body does not define the '%s' field", MXS_JSON_PTR_PARAM_ADDRESS); config_runtime_error("Request body does not define '%s' or '%s'",
MXS_JSON_PTR_PARAM_ADDRESS, MXS_JSON_PTR_PARAM_SOCKET);
} }
else if (!json_is_string(address)) else if (address && socket)
{
config_runtime_error("Request body defines both of the '%s' and '%s' fields",
MXS_JSON_PTR_PARAM_ADDRESS, MXS_JSON_PTR_PARAM_SOCKET);
}
else if (address && !json_is_string(address))
{ {
config_runtime_error("The '%s' field is not a string", MXS_JSON_PTR_PARAM_ADDRESS); config_runtime_error("The '%s' field is not a string", MXS_JSON_PTR_PARAM_ADDRESS);
} }
else if (!port) else if (address && json_is_string(address) && json_string_value(address)[0] == '/')
{
config_runtime_error("The '%s' field is not a valid address", MXS_JSON_PTR_PARAM_ADDRESS);
}
else if (socket && !json_is_string(socket))
{
config_runtime_error("The '%s' field is not a string", MXS_JSON_PTR_PARAM_SOCKET);
}
else if (!address && port)
{ {
config_runtime_error("Request body does not define the '%s' field", MXS_JSON_PTR_PARAM_PORT); config_runtime_error("Request body does not define the '%s' field", MXS_JSON_PTR_PARAM_PORT);
} }
else if (!json_is_integer(port)) else if (port && !json_is_integer(port))
{ {
config_runtime_error("The '%s' field is not an integer", MXS_JSON_PTR_PARAM_PORT); config_runtime_error("The '%s' field is not an integer", MXS_JSON_PTR_PARAM_PORT);
} }
@ -1958,11 +2014,14 @@ Server* runtime_create_server_from_json(json_t* json)
{ {
Server* rval = NULL; Server* rval = NULL;
if (is_valid_resource_body(json) if (is_valid_resource_body(json) && server_contains_required_fields(json))
&& server_contains_required_fields(json))
{ {
const char* name = json_string_value(mxs_json_pointer(json, MXS_JSON_PTR_ID)); const char* name = json_string_value(mxs_json_pointer(json, MXS_JSON_PTR_ID));
const char* address = json_string_value(mxs_json_pointer(json, MXS_JSON_PTR_PARAM_ADDRESS));
// Either `address` or `socket` is defined, not both
json_t* addr = mxs_json_pointer(json, MXS_JSON_PTR_PARAM_ADDRESS);
json_t* sock = mxs_json_pointer(json, MXS_JSON_PTR_PARAM_SOCKET);
const char* address = addr ? json_string_value(addr) : json_string_value(sock);
/** The port needs to be in string format */ /** The port needs to be in string format */
std::string port = json_int_to_string(mxs_json_pointer(json, MXS_JSON_PTR_PARAM_PORT)); std::string port = json_int_to_string(mxs_json_pointer(json, MXS_JSON_PTR_PARAM_PORT));
@ -2076,7 +2135,8 @@ bool runtime_alter_server_from_json(Server* server, json_t* new_json)
mxb_assert(old_json.get()); mxb_assert(old_json.get());
if (is_valid_resource_body(new_json) if (is_valid_resource_body(new_json)
&& server_to_object_relations(server, old_json.get(), new_json)) && server_to_object_relations(server, old_json.get(), new_json)
&& server_alter_fields_are_valid(new_json))
{ {
rval = true; rval = true;
json_t* parameters = mxs_json_pointer(new_json, MXS_JSON_PTR_PARAMETERS); json_t* parameters = mxs_json_pointer(new_json, MXS_JSON_PTR_PARAMETERS);

View File

@ -242,7 +242,9 @@ Server* Server::server_alloc(const char* name, MXS_CONFIG_PARAMETER* params)
return NULL; return NULL;
} }
auto address = params->get_string(CN_ADDRESS); auto address = params->contains(CN_ADDRESS) ?
params->get_string(CN_ADDRESS) : params->get_string(CN_SOCKET);
careful_strcpy(server->address, MAX_ADDRESS_LEN, address.c_str()); careful_strcpy(server->address, MAX_ADDRESS_LEN, address.c_str());
if (address.length() > MAX_ADDRESS_LEN) if (address.length() > MAX_ADDRESS_LEN)
{ {