From 993334b9fdcf5e84425f0fafb3a19898681e0a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Fri, 12 Apr 2019 12:13:15 +0300 Subject: [PATCH] MXS-2349: Add `socket` parameter Servers now accept the `socket` parameter in the configuration as well as in the REST API. --- include/maxscale/config.hh | 1 + server/core/config.cc | 29 +++++++++++-- server/core/config_runtime.cc | 82 ++++++++++++++++++++++++++++++----- server/core/server.cc | 4 +- 4 files changed, 101 insertions(+), 15 deletions(-) diff --git a/include/maxscale/config.hh b/include/maxscale/config.hh index c8d6c2367..ecae2867e 100644 --- a/include/maxscale/config.hh +++ b/include/maxscale/config.hh @@ -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" diff --git a/server/core/config.cc b/server/core/config.cc index 58124438c..8082c2f82 100644 --- a/server/core/config.cc +++ b/server/core/config.cc @@ -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); diff --git a/server/core/config_runtime.cc b/server/core/config_runtime.cc index b87b83df3..95167aa8e 100644 --- a/server/core/config_runtime.cc +++ b/server/core/config_runtime.cc @@ -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 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); diff --git a/server/core/server.cc b/server/core/server.cc index a4e7a1ce7..406595a1b 100644 --- a/server/core/server.cc +++ b/server/core/server.cc @@ -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) {