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
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
4 changed files with 101 additions and 15 deletions

View File

@ -61,6 +61,7 @@ class SERVICE;
/** Parameter value JSON Pointers */
#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_SOCKET MXS_JSON_PTR_PARAMETERS "/socket"
#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_OPTIONS MXS_JSON_PTR_PARAMETERS "/authenticator_options"

View File

@ -592,9 +592,11 @@ const MXS_MODULE_PARAM config_server_params[] =
},
{
CN_ADDRESS,
MXS_MODULE_PARAM_STRING,
NULL,
MXS_MODULE_OPT_REQUIRED
MXS_MODULE_PARAM_STRING
},
{
CN_SOCKET,
MXS_MODULE_PARAM_STRING
},
{
CN_PROTOCOL,
@ -3974,6 +3976,27 @@ int create_new_server(CONFIG_CONTEXT* obj)
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))
{
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)
{
parameters.set(CN_ADDRESS, address);
auto param_name = *address == '/' ? CN_SOCKET : CN_ADDRESS;
parameters.set(param_name, address);
}
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);
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);
}
@ -1740,11 +1741,52 @@ static bool is_valid_resource_body(json_t* json)
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)
{
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* 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;
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);
}
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);
}
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);
}
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);
}
@ -1958,11 +2014,14 @@ Server* runtime_create_server_from_json(json_t* json)
{
Server* rval = NULL;
if (is_valid_resource_body(json)
&& server_contains_required_fields(json))
if (is_valid_resource_body(json) && server_contains_required_fields(json))
{
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 */
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());
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;
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;
}
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());
if (address.length() > MAX_ADDRESS_LEN)
{