|
|
|
@ -458,7 +458,7 @@ const char* deprecated_server_params[] =
|
|
|
|
|
|
|
|
|
|
void config_finish()
|
|
|
|
|
{
|
|
|
|
|
config_context_free(config_context.next);
|
|
|
|
|
config_context_free(config_context.m_next);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -596,9 +596,9 @@ char* config_clean_string_list(const char* str)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CONFIG_CONTEXT::CONFIG_CONTEXT(const string& section)
|
|
|
|
|
: name(section)
|
|
|
|
|
, was_persisted(is_persisted_config)
|
|
|
|
|
, next(nullptr)
|
|
|
|
|
: m_name(section)
|
|
|
|
|
, m_was_persisted(is_persisted_config)
|
|
|
|
|
, m_next(nullptr)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -735,9 +735,9 @@ static int ini_handler(void* userdata, const char* section, const char* name, co
|
|
|
|
|
* add the parameters to that object. If not create
|
|
|
|
|
* a new object.
|
|
|
|
|
*/
|
|
|
|
|
while (ptr && strcmp(ptr->object(), section) != 0)
|
|
|
|
|
while (ptr && strcmp(ptr->name(), section) != 0)
|
|
|
|
|
{
|
|
|
|
|
ptr = ptr->next;
|
|
|
|
|
ptr = ptr->m_next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ptr)
|
|
|
|
@ -747,11 +747,11 @@ static int ini_handler(void* userdata, const char* section, const char* name, co
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ptr->next = cntxt->next;
|
|
|
|
|
cntxt->next = ptr;
|
|
|
|
|
ptr->m_next = cntxt->m_next;
|
|
|
|
|
cntxt->m_next = ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ptr->parameters.contains(name))
|
|
|
|
|
if (ptr->m_parameters.contains(name))
|
|
|
|
|
{
|
|
|
|
|
/** The values in the persisted configurations are updated versions of
|
|
|
|
|
* the ones in the main configuration file. */
|
|
|
|
@ -1048,7 +1048,7 @@ bool export_config_file(const char* filename)
|
|
|
|
|
|
|
|
|
|
// The config objects are stored in reverse order so first convert it back
|
|
|
|
|
// to the correct order
|
|
|
|
|
for (CONFIG_CONTEXT* ctx = config_context.next; ctx; ctx = ctx->next)
|
|
|
|
|
for (CONFIG_CONTEXT* ctx = config_context.m_next; ctx; ctx = ctx->m_next)
|
|
|
|
|
{
|
|
|
|
|
contexts.push_back(ctx);
|
|
|
|
|
}
|
|
|
|
@ -1065,8 +1065,8 @@ bool export_config_file(const char* filename)
|
|
|
|
|
{
|
|
|
|
|
CONFIG_CONTEXT* ctx = *it;
|
|
|
|
|
|
|
|
|
|
file << '[' << ctx->name << "]\n";
|
|
|
|
|
for (const auto& elem : ctx->parameters)
|
|
|
|
|
file << '[' << ctx->m_name << "]\n";
|
|
|
|
|
for (const auto& elem : ctx->m_parameters)
|
|
|
|
|
{
|
|
|
|
|
file << elem.first << '=' << elem.second << '\n';
|
|
|
|
|
}
|
|
|
|
@ -1163,7 +1163,7 @@ static bool config_load_and_process(const char* filename, bool (* process_config
|
|
|
|
|
|
|
|
|
|
if (rval)
|
|
|
|
|
{
|
|
|
|
|
if (!check_config_objects(config_context.next) || !process_config(config_context.next))
|
|
|
|
|
if (!check_config_objects(config_context.m_next) || !process_config(config_context.m_next))
|
|
|
|
|
{
|
|
|
|
|
rval = false;
|
|
|
|
|
if (have_persisted_configs)
|
|
|
|
@ -1234,17 +1234,17 @@ bool valid_object_type(std::string type)
|
|
|
|
|
|
|
|
|
|
const char* get_missing_module_parameter_name(const CONFIG_CONTEXT* obj)
|
|
|
|
|
{
|
|
|
|
|
std::string type = obj->parameters.get_string(CN_TYPE);
|
|
|
|
|
std::string type = obj->m_parameters.get_string(CN_TYPE);
|
|
|
|
|
|
|
|
|
|
if (type == CN_SERVICE && !obj->parameters.contains(CN_ROUTER))
|
|
|
|
|
if (type == CN_SERVICE && !obj->m_parameters.contains(CN_ROUTER))
|
|
|
|
|
{
|
|
|
|
|
return CN_ROUTER;
|
|
|
|
|
}
|
|
|
|
|
else if ((type == CN_LISTENER || type == CN_SERVER) && !obj->parameters.contains(CN_PROTOCOL))
|
|
|
|
|
else if ((type == CN_LISTENER || type == CN_SERVER) && !obj->m_parameters.contains(CN_PROTOCOL))
|
|
|
|
|
{
|
|
|
|
|
return CN_PROTOCOL;
|
|
|
|
|
}
|
|
|
|
|
else if ((type == CN_MONITOR || type == CN_FILTER) && !obj->parameters.contains(CN_MODULE))
|
|
|
|
|
else if ((type == CN_MONITOR || type == CN_FILTER) && !obj->m_parameters.contains(CN_MODULE))
|
|
|
|
|
{
|
|
|
|
|
return CN_MODULE;
|
|
|
|
|
}
|
|
|
|
@ -1253,31 +1253,31 @@ const char* get_missing_module_parameter_name(const CONFIG_CONTEXT* obj)
|
|
|
|
|
|
|
|
|
|
std::pair<const MXS_MODULE_PARAM*, const MXS_MODULE*> get_module_details(const CONFIG_CONTEXT* obj)
|
|
|
|
|
{
|
|
|
|
|
std::string type = obj->parameters.get_string(CN_TYPE);
|
|
|
|
|
std::string type = obj->m_parameters.get_string(CN_TYPE);
|
|
|
|
|
|
|
|
|
|
if (type == CN_SERVICE)
|
|
|
|
|
{
|
|
|
|
|
auto name = obj->parameters.get_string(CN_ROUTER);
|
|
|
|
|
auto name = obj->m_parameters.get_string(CN_ROUTER);
|
|
|
|
|
return {config_service_params, get_module(name.c_str(), MODULE_ROUTER)};
|
|
|
|
|
}
|
|
|
|
|
else if (type == CN_LISTENER)
|
|
|
|
|
{
|
|
|
|
|
auto name = obj->parameters.get_string(CN_PROTOCOL);
|
|
|
|
|
auto name = obj->m_parameters.get_string(CN_PROTOCOL);
|
|
|
|
|
return {config_listener_params, get_module(name.c_str(), MODULE_PROTOCOL)};
|
|
|
|
|
}
|
|
|
|
|
else if (type == CN_SERVER)
|
|
|
|
|
{
|
|
|
|
|
auto name = obj->parameters.get_string(CN_PROTOCOL);
|
|
|
|
|
auto name = obj->m_parameters.get_string(CN_PROTOCOL);
|
|
|
|
|
return {config_server_params, get_module(name.c_str(), MODULE_PROTOCOL)};
|
|
|
|
|
}
|
|
|
|
|
else if (type == CN_MONITOR)
|
|
|
|
|
{
|
|
|
|
|
auto name = obj->parameters.get_string(CN_MODULE);
|
|
|
|
|
auto name = obj->m_parameters.get_string(CN_MODULE);
|
|
|
|
|
return {config_monitor_params, get_module(name.c_str(), MODULE_MONITOR)};
|
|
|
|
|
}
|
|
|
|
|
else if (type == CN_FILTER)
|
|
|
|
|
{
|
|
|
|
|
auto name = obj->parameters.get_string(CN_MODULE);
|
|
|
|
|
auto name = obj->m_parameters.get_string(CN_MODULE);
|
|
|
|
|
return {config_filter_params, get_module(name.c_str(), MODULE_FILTER)};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1294,7 +1294,7 @@ CONFIG_CONTEXT* name_to_object(const std::vector<CONFIG_CONTEXT*>& objects,
|
|
|
|
|
fix_object_name(name);
|
|
|
|
|
|
|
|
|
|
auto equal_name = [&](CONFIG_CONTEXT* c) {
|
|
|
|
|
std::string s = c->name;
|
|
|
|
|
std::string s = c->m_name;
|
|
|
|
|
fix_object_name(s);
|
|
|
|
|
return s == name;
|
|
|
|
|
};
|
|
|
|
@ -1306,7 +1306,7 @@ CONFIG_CONTEXT* name_to_object(const std::vector<CONFIG_CONTEXT*>& objects,
|
|
|
|
|
MXS_ERROR("Could not find object '%s' that '%s' depends on. "
|
|
|
|
|
"Check that the configuration object exists.",
|
|
|
|
|
name.c_str(),
|
|
|
|
|
obj->object());
|
|
|
|
|
obj->name());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -1333,36 +1333,36 @@ std::unordered_set<CONFIG_CONTEXT*> get_dependencies(const std::vector<CONFIG_CO
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; p[i].name; i++)
|
|
|
|
|
{
|
|
|
|
|
if (obj->parameters.contains(p[i].name))
|
|
|
|
|
if (obj->m_parameters.contains(p[i].name))
|
|
|
|
|
{
|
|
|
|
|
if (p[i].type == MXS_MODULE_PARAM_SERVICE
|
|
|
|
|
|| p[i].type == MXS_MODULE_PARAM_SERVER)
|
|
|
|
|
{
|
|
|
|
|
std::string v = obj->parameters.get_string(p[i].name);
|
|
|
|
|
std::string v = obj->m_parameters.get_string(p[i].name);
|
|
|
|
|
rval.insert(name_to_object(objects, obj, v));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string type = obj->parameters.get_string(CN_TYPE);
|
|
|
|
|
std::string type = obj->m_parameters.get_string(CN_TYPE);
|
|
|
|
|
|
|
|
|
|
if (type == CN_SERVICE && obj->parameters.contains(CN_FILTERS))
|
|
|
|
|
if (type == CN_SERVICE && obj->m_parameters.contains(CN_FILTERS))
|
|
|
|
|
{
|
|
|
|
|
for (std::string name : mxs::strtok(obj->parameters.get_string(CN_FILTERS), "|"))
|
|
|
|
|
for (std::string name : mxs::strtok(obj->m_parameters.get_string(CN_FILTERS), "|"))
|
|
|
|
|
{
|
|
|
|
|
rval.insert(name_to_object(objects, obj, name));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (type == CN_SERVICE && obj->parameters.contains(CN_CLUSTER))
|
|
|
|
|
if (type == CN_SERVICE && obj->m_parameters.contains(CN_CLUSTER))
|
|
|
|
|
{
|
|
|
|
|
rval.insert(name_to_object(objects, obj, obj->parameters.get_string(CN_CLUSTER)));
|
|
|
|
|
rval.insert(name_to_object(objects, obj, obj->m_parameters.get_string(CN_CLUSTER)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((type == CN_MONITOR || type == CN_SERVICE) && obj->parameters.contains(CN_SERVERS))
|
|
|
|
|
if ((type == CN_MONITOR || type == CN_SERVICE) && obj->m_parameters.contains(CN_SERVERS))
|
|
|
|
|
{
|
|
|
|
|
for (std::string name : mxs::strtok(obj->parameters.get_string(CN_SERVERS), ","))
|
|
|
|
|
for (std::string name : mxs::strtok(obj->m_parameters.get_string(CN_SERVERS), ","))
|
|
|
|
|
{
|
|
|
|
|
rval.insert(name_to_object(objects, obj, name));
|
|
|
|
|
}
|
|
|
|
@ -1533,10 +1533,10 @@ bool resolve_dependencies(std::vector<CONFIG_CONTEXT*>& objects)
|
|
|
|
|
if (group.size() > 1)
|
|
|
|
|
{
|
|
|
|
|
auto join = [](std::string total, CONFIG_CONTEXT* c) {
|
|
|
|
|
return total + " -> " + c->name;
|
|
|
|
|
return total + " -> " + c->m_name;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::string first = group[0]->name;
|
|
|
|
|
std::string first = group[0]->m_name;
|
|
|
|
|
std::string str_group = std::accumulate(std::next(group.begin()), group.end(), first, join);
|
|
|
|
|
str_group += " -> " + first;
|
|
|
|
|
MXS_ERROR("A circular dependency chain was found in the configuration: %s",
|
|
|
|
@ -1574,9 +1574,9 @@ static bool process_config_context(CONFIG_CONTEXT* context)
|
|
|
|
|
{
|
|
|
|
|
std::vector<CONFIG_CONTEXT*> objects;
|
|
|
|
|
|
|
|
|
|
for (CONFIG_CONTEXT* obj = context; obj; obj = obj->next)
|
|
|
|
|
for (CONFIG_CONTEXT* obj = context; obj; obj = obj->m_next)
|
|
|
|
|
{
|
|
|
|
|
if (!is_maxscale_section(obj->object()))
|
|
|
|
|
if (!is_maxscale_section(obj->name()))
|
|
|
|
|
{
|
|
|
|
|
objects.push_back(obj);
|
|
|
|
|
}
|
|
|
|
@ -1590,7 +1590,7 @@ static bool process_config_context(CONFIG_CONTEXT* context)
|
|
|
|
|
*/
|
|
|
|
|
for (CONFIG_CONTEXT* obj : objects)
|
|
|
|
|
{
|
|
|
|
|
std::string type = obj->parameters.get_string(CN_TYPE);
|
|
|
|
|
std::string type = obj->m_parameters.get_string(CN_TYPE);
|
|
|
|
|
mxb_assert(!type.empty());
|
|
|
|
|
|
|
|
|
|
if (type == CN_SERVER)
|
|
|
|
@ -1612,7 +1612,7 @@ static bool process_config_context(CONFIG_CONTEXT* context)
|
|
|
|
|
*/
|
|
|
|
|
for (CONFIG_CONTEXT* obj : objects)
|
|
|
|
|
{
|
|
|
|
|
std::string type = obj->parameters.get_string(CN_TYPE);
|
|
|
|
|
std::string type = obj->m_parameters.get_string(CN_TYPE);
|
|
|
|
|
mxb_assert(!type.empty());
|
|
|
|
|
|
|
|
|
|
if (type == CN_SERVICE)
|
|
|
|
@ -1852,7 +1852,7 @@ void config_context_free(CONFIG_CONTEXT* context)
|
|
|
|
|
CONFIG_CONTEXT* obj;
|
|
|
|
|
while (context)
|
|
|
|
|
{
|
|
|
|
|
obj = context->next;
|
|
|
|
|
obj = context->m_next;
|
|
|
|
|
delete context;
|
|
|
|
|
context = obj;
|
|
|
|
|
}
|
|
|
|
@ -1860,22 +1860,22 @@ void config_context_free(CONFIG_CONTEXT* context)
|
|
|
|
|
|
|
|
|
|
bool config_add_param(CONFIG_CONTEXT* obj, const char* key, const char* value)
|
|
|
|
|
{
|
|
|
|
|
mxb_assert(!obj->parameters.contains(key));
|
|
|
|
|
obj->parameters.set(key, value);
|
|
|
|
|
mxb_assert(!obj->m_parameters.contains(key));
|
|
|
|
|
obj->m_parameters.set(key, value);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool config_append_param(CONFIG_CONTEXT* obj, const char* key, const char* value)
|
|
|
|
|
{
|
|
|
|
|
mxb_assert(obj->parameters.contains(key));
|
|
|
|
|
auto old_val = obj->parameters.get_string(key);
|
|
|
|
|
mxb_assert(obj->m_parameters.contains(key));
|
|
|
|
|
auto old_val = obj->m_parameters.get_string(key);
|
|
|
|
|
string new_val = old_val + "," + value;
|
|
|
|
|
char* new_val_z = config_clean_string_list(new_val.c_str());
|
|
|
|
|
|
|
|
|
|
bool rval = false;
|
|
|
|
|
if (new_val_z)
|
|
|
|
|
{
|
|
|
|
|
obj->parameters.set(key, new_val_z);
|
|
|
|
|
obj->m_parameters.set(key, new_val_z);
|
|
|
|
|
MXS_FREE(new_val_z);
|
|
|
|
|
rval = true;
|
|
|
|
|
}
|
|
|
|
@ -1939,13 +1939,13 @@ MXS_CONFIG_PARAMETER::ContainerType::const_iterator MXS_CONFIG_PARAMETER::end()
|
|
|
|
|
|
|
|
|
|
bool config_replace_param(CONFIG_CONTEXT* obj, const char* key, const char* value)
|
|
|
|
|
{
|
|
|
|
|
obj->parameters.set(key, value);
|
|
|
|
|
obj->m_parameters.set(key, value);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void config_remove_param(CONFIG_CONTEXT* obj, const char* name)
|
|
|
|
|
{
|
|
|
|
|
obj->parameters.remove(name);
|
|
|
|
|
obj->m_parameters.remove(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -2917,18 +2917,18 @@ static bool check_config_objects(CONFIG_CONTEXT* context)
|
|
|
|
|
{
|
|
|
|
|
bool rval = true;
|
|
|
|
|
|
|
|
|
|
for (CONFIG_CONTEXT* obj = context; obj; obj = obj->next)
|
|
|
|
|
for (CONFIG_CONTEXT* obj = context; obj; obj = obj->m_next)
|
|
|
|
|
{
|
|
|
|
|
if (is_maxscale_section(obj->object()))
|
|
|
|
|
if (is_maxscale_section(obj->name()))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string type = obj->parameters.get_string(CN_TYPE);
|
|
|
|
|
std::string type = obj->m_parameters.get_string(CN_TYPE);
|
|
|
|
|
|
|
|
|
|
if (!valid_object_type(type))
|
|
|
|
|
{
|
|
|
|
|
MXS_ERROR("Unknown module type for object '%s': %s", obj->object(), type.c_str());
|
|
|
|
|
MXS_ERROR("Unknown module type for object '%s': %s", obj->name(), type.c_str());
|
|
|
|
|
rval = false;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
@ -2937,7 +2937,7 @@ static bool check_config_objects(CONFIG_CONTEXT* context)
|
|
|
|
|
|
|
|
|
|
if (no_module_defined)
|
|
|
|
|
{
|
|
|
|
|
MXS_ERROR("'%s' is missing the required parameter '%s'", obj->object(), no_module_defined);
|
|
|
|
|
MXS_ERROR("'%s' is missing the required parameter '%s'", obj->name(), no_module_defined);
|
|
|
|
|
rval = false;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
@ -2955,7 +2955,7 @@ static bool check_config_objects(CONFIG_CONTEXT* context)
|
|
|
|
|
mxb_assert(param_set);
|
|
|
|
|
std::vector<std::string> to_be_removed;
|
|
|
|
|
|
|
|
|
|
for (auto iter = obj->parameters.begin(); iter != obj->parameters.end(); ++iter)
|
|
|
|
|
for (auto iter = obj->m_parameters.begin(); iter != obj->m_parameters.end(); ++iter)
|
|
|
|
|
{
|
|
|
|
|
const char* param_namez = iter->first.c_str();
|
|
|
|
|
const MXS_MODULE_PARAM* fix_params;
|
|
|
|
@ -2975,7 +2975,7 @@ static bool check_config_objects(CONFIG_CONTEXT* context)
|
|
|
|
|
if (type != CN_SERVER)
|
|
|
|
|
{
|
|
|
|
|
MXS_ERROR("Unknown parameter '%s' for object '%s' of type '%s'. %s",
|
|
|
|
|
param_namez, obj->object(), type.c_str(),
|
|
|
|
|
param_namez, obj->name(), type.c_str(),
|
|
|
|
|
closest_matching_parameter(param_namez, param_set, mod->parameters).c_str());
|
|
|
|
|
rval = false;
|
|
|
|
|
}
|
|
|
|
@ -2994,9 +2994,9 @@ static bool check_config_objects(CONFIG_CONTEXT* context)
|
|
|
|
|
{
|
|
|
|
|
config_fix_param(fix_params, param_namez, &temp);
|
|
|
|
|
}
|
|
|
|
|
obj->parameters.set(param_namez, temp);
|
|
|
|
|
obj->m_parameters.set(param_namez, temp);
|
|
|
|
|
|
|
|
|
|
if (param_is_deprecated(fix_params, param_namez, obj->object()))
|
|
|
|
|
if (param_is_deprecated(fix_params, param_namez, obj->name()))
|
|
|
|
|
{
|
|
|
|
|
to_be_removed.push_back(param_namez);
|
|
|
|
|
}
|
|
|
|
@ -3005,7 +3005,7 @@ static bool check_config_objects(CONFIG_CONTEXT* context)
|
|
|
|
|
{
|
|
|
|
|
MXS_ERROR("Invalid value '%s' for parameter '%s' for object '%s' "
|
|
|
|
|
"of type '%s' (was expecting %s)",
|
|
|
|
|
param_value.c_str(), param_namez, obj->object(),
|
|
|
|
|
param_value.c_str(), param_namez, obj->name(),
|
|
|
|
|
type.c_str(),
|
|
|
|
|
param_type_to_str(fix_params, param_namez));
|
|
|
|
|
rval = false;
|
|
|
|
@ -3017,8 +3017,8 @@ static bool check_config_objects(CONFIG_CONTEXT* context)
|
|
|
|
|
config_remove_param(obj, a.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (missing_required_parameters(param_set, obj->parameters, obj->object())
|
|
|
|
|
|| missing_required_parameters(mod->parameters, obj->parameters, obj->object()))
|
|
|
|
|
if (missing_required_parameters(param_set, obj->m_parameters, obj->name())
|
|
|
|
|
|| missing_required_parameters(mod->parameters, obj->m_parameters, obj->name()))
|
|
|
|
|
{
|
|
|
|
|
rval = false;
|
|
|
|
|
}
|
|
|
|
@ -3395,13 +3395,13 @@ static int validate_ssl_parameters(CONFIG_CONTEXT* obj, char* ssl_cert, char* ss
|
|
|
|
|
MXS_ERROR("Server certificate missing for listener '%s'."
|
|
|
|
|
"Please provide the path to the server certificate by adding "
|
|
|
|
|
"the ssl_cert=<path> parameter",
|
|
|
|
|
obj->object());
|
|
|
|
|
obj->name());
|
|
|
|
|
}
|
|
|
|
|
else if (access(ssl_cert, F_OK) != 0)
|
|
|
|
|
{
|
|
|
|
|
error_count++;
|
|
|
|
|
MXS_ERROR("Server certificate file for listener '%s' not found: %s",
|
|
|
|
|
obj->object(),
|
|
|
|
|
obj->name(),
|
|
|
|
|
ssl_cert);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -3411,14 +3411,14 @@ static int validate_ssl_parameters(CONFIG_CONTEXT* obj, char* ssl_cert, char* ss
|
|
|
|
|
MXS_ERROR("CA Certificate missing for listener '%s'."
|
|
|
|
|
"Please provide the path to the certificate authority "
|
|
|
|
|
"certificate by adding the ssl_ca_cert=<path> parameter",
|
|
|
|
|
obj->object());
|
|
|
|
|
obj->name());
|
|
|
|
|
}
|
|
|
|
|
else if (access(ssl_ca_cert, F_OK) != 0)
|
|
|
|
|
{
|
|
|
|
|
error_count++;
|
|
|
|
|
MXS_ERROR("Certificate authority file for listener '%s' "
|
|
|
|
|
"not found: %s",
|
|
|
|
|
obj->object(),
|
|
|
|
|
obj->name(),
|
|
|
|
|
ssl_ca_cert);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -3428,13 +3428,13 @@ static int validate_ssl_parameters(CONFIG_CONTEXT* obj, char* ssl_cert, char* ss
|
|
|
|
|
MXS_ERROR("Server private key missing for listener '%s'. "
|
|
|
|
|
"Please provide the path to the server certificate key by "
|
|
|
|
|
"adding the ssl_key=<path> parameter",
|
|
|
|
|
obj->object());
|
|
|
|
|
obj->name());
|
|
|
|
|
}
|
|
|
|
|
else if (access(ssl_key, F_OK) != 0)
|
|
|
|
|
{
|
|
|
|
|
error_count++;
|
|
|
|
|
MXS_ERROR("Server private key file for listener '%s' not found: %s",
|
|
|
|
|
obj->object(),
|
|
|
|
|
obj->name(),
|
|
|
|
|
ssl_key);
|
|
|
|
|
}
|
|
|
|
|
return error_count;
|
|
|
|
@ -3455,7 +3455,7 @@ void config_add_defaults(CONFIG_CONTEXT* ctx, const MXS_MODULE_PARAM* params)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; params[i].name; i++)
|
|
|
|
|
{
|
|
|
|
|
if (params[i].default_value && !ctx->parameters.contains(params[i].name))
|
|
|
|
|
if (params[i].default_value && !ctx->m_parameters.contains(params[i].name))
|
|
|
|
|
{
|
|
|
|
|
bool rv = config_add_param(ctx, params[i].name, params[i].default_value);
|
|
|
|
|
MXS_ABORT_IF_FALSE(rv);
|
|
|
|
@ -3542,21 +3542,21 @@ void config_add_module_params_json(const MXS_CONFIG_PARAMETER* parameters,
|
|
|
|
|
*/
|
|
|
|
|
int create_new_service(CONFIG_CONTEXT* obj)
|
|
|
|
|
{
|
|
|
|
|
auto router = obj->parameters.get_string(CN_ROUTER);
|
|
|
|
|
auto router = obj->m_parameters.get_string(CN_ROUTER);
|
|
|
|
|
mxb_assert(!router.empty());
|
|
|
|
|
|
|
|
|
|
const string servers = obj->parameters.get_string(CN_SERVERS);
|
|
|
|
|
const string cluster = obj->parameters.get_string(CN_CLUSTER);
|
|
|
|
|
const string servers = obj->m_parameters.get_string(CN_SERVERS);
|
|
|
|
|
const string cluster = obj->m_parameters.get_string(CN_CLUSTER);
|
|
|
|
|
|
|
|
|
|
if (!servers.empty() && !cluster.empty())
|
|
|
|
|
{
|
|
|
|
|
MXS_ERROR("Service '%s' is configured with both 'servers' and 'cluster'. "
|
|
|
|
|
"Only one or the other is allowed.", obj->object());
|
|
|
|
|
"Only one or the other is allowed.", obj->name());
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string user = obj->parameters.get_string(CN_USER);
|
|
|
|
|
string auth = obj->parameters.get_string(CN_PASSWORD);
|
|
|
|
|
string user = obj->m_parameters.get_string(CN_USER);
|
|
|
|
|
string auth = obj->m_parameters.get_string(CN_PASSWORD);
|
|
|
|
|
const MXS_MODULE* module = get_module(router.c_str(), MODULE_ROUTER);
|
|
|
|
|
mxb_assert(module);
|
|
|
|
|
|
|
|
|
@ -3564,7 +3564,7 @@ int create_new_service(CONFIG_CONTEXT* obj)
|
|
|
|
|
&& !rcap_type_required(module->module_capabilities, RCAP_TYPE_NO_AUTH))
|
|
|
|
|
{
|
|
|
|
|
MXS_ERROR("Service '%s' is missing %s%s%s.",
|
|
|
|
|
obj->object(),
|
|
|
|
|
obj->name(),
|
|
|
|
|
!user.empty() ? "" : "the 'user' parameter",
|
|
|
|
|
user.empty() && auth.empty() ? " and " : "",
|
|
|
|
|
!auth.empty() ? "" : "the 'password' parameter");
|
|
|
|
@ -3574,7 +3574,7 @@ int create_new_service(CONFIG_CONTEXT* obj)
|
|
|
|
|
config_add_defaults(obj, config_service_params);
|
|
|
|
|
config_add_defaults(obj, module->parameters);
|
|
|
|
|
|
|
|
|
|
Service* service = service_alloc(obj->object(), router.c_str(), &obj->parameters);
|
|
|
|
|
Service* service = service_alloc(obj->name(), router.c_str(), &obj->m_parameters);
|
|
|
|
|
|
|
|
|
|
if (service)
|
|
|
|
|
{
|
|
|
|
@ -3595,13 +3595,13 @@ int create_new_service(CONFIG_CONTEXT* obj)
|
|
|
|
|
MXS_ERROR("Unable to find server '%s' that is configured as part "
|
|
|
|
|
"of service '%s'.",
|
|
|
|
|
a.c_str(),
|
|
|
|
|
obj->object());
|
|
|
|
|
obj->name());
|
|
|
|
|
error_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string filters = obj->parameters.get_string(CN_FILTERS);
|
|
|
|
|
string filters = obj->m_parameters.get_string(CN_FILTERS);
|
|
|
|
|
if (!filters.empty())
|
|
|
|
|
{
|
|
|
|
|
auto flist = mxs::strtok(filters, "|");
|
|
|
|
@ -3623,14 +3623,14 @@ int create_new_service(CONFIG_CONTEXT* obj)
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
MXS_ERROR("Unable to find monitor '%s' that defines the cluster used by "
|
|
|
|
|
"service '%s'.", cluster.c_str(), obj->object());
|
|
|
|
|
"service '%s'.", cluster.c_str(), obj->name());
|
|
|
|
|
error_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
MXS_ERROR("Service '%s' creation failed.", obj->object());
|
|
|
|
|
MXS_ERROR("Service '%s' creation failed.", obj->name());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return service ? 0 : 1;
|
|
|
|
@ -3673,7 +3673,7 @@ int create_new_server(CONFIG_CONTEXT* obj)
|
|
|
|
|
|
|
|
|
|
config_add_defaults(obj, config_server_params);
|
|
|
|
|
|
|
|
|
|
auto module = obj->parameters.get_string(CN_PROTOCOL);
|
|
|
|
|
auto module = obj->m_parameters.get_string(CN_PROTOCOL);
|
|
|
|
|
mxb_assert(!module.empty());
|
|
|
|
|
|
|
|
|
|
if (const MXS_MODULE* mod = get_module(module.c_str(), MODULE_PROTOCOL))
|
|
|
|
@ -3686,9 +3686,9 @@ int create_new_server(CONFIG_CONTEXT* obj)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Server* server = Server::server_alloc(obj->object(), &obj->parameters))
|
|
|
|
|
if (Server* server = Server::server_alloc(obj->name(), &obj->m_parameters))
|
|
|
|
|
{
|
|
|
|
|
auto disk_space_threshold = obj->parameters.get_string(CN_DISK_SPACE_THRESHOLD);
|
|
|
|
|
auto disk_space_threshold = obj->m_parameters.get_string(CN_DISK_SPACE_THRESHOLD);
|
|
|
|
|
if (!server->set_disk_space_threshold(disk_space_threshold))
|
|
|
|
|
{
|
|
|
|
|
MXS_ERROR("Invalid value for '%s' for server %s: %s",
|
|
|
|
@ -3719,7 +3719,7 @@ int create_new_monitor(CONFIG_CONTEXT* obj, std::set<std::string>& monitored_ser
|
|
|
|
|
{
|
|
|
|
|
bool err = false;
|
|
|
|
|
|
|
|
|
|
MXS_CONFIG_PARAMETER* params = &obj->parameters;
|
|
|
|
|
MXS_CONFIG_PARAMETER* params = &obj->m_parameters;
|
|
|
|
|
// The config loader has already checked that the server list is mostly ok. However, it cannot
|
|
|
|
|
// check that the server names in the list actually ended up generated.
|
|
|
|
|
if (params->contains(CN_SERVERS))
|
|
|
|
@ -3731,7 +3731,7 @@ int create_new_monitor(CONFIG_CONTEXT* obj, std::set<std::string>& monitored_ser
|
|
|
|
|
err = true;
|
|
|
|
|
mxb_assert(!name_not_found.empty());
|
|
|
|
|
MXS_ERROR("Unable to find server '%s' that is configured in monitor '%s'.",
|
|
|
|
|
name_not_found.c_str(), obj->object());
|
|
|
|
|
name_not_found.c_str(), obj->name());
|
|
|
|
|
}
|
|
|
|
|
for (auto server : servers)
|
|
|
|
|
{
|
|
|
|
@ -3749,7 +3749,7 @@ int create_new_monitor(CONFIG_CONTEXT* obj, std::set<std::string>& monitored_ser
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto module = obj->parameters.get_string(CN_MODULE);
|
|
|
|
|
auto module = obj->m_parameters.get_string(CN_MODULE);
|
|
|
|
|
mxb_assert(!module.empty());
|
|
|
|
|
|
|
|
|
|
if (const MXS_MODULE* mod = get_module(module.c_str(), MODULE_MONITOR))
|
|
|
|
@ -3763,10 +3763,10 @@ int create_new_monitor(CONFIG_CONTEXT* obj, std::set<std::string>& monitored_ser
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Monitor* monitor = MonitorManager::create_monitor(obj->object(), module, &obj->parameters);
|
|
|
|
|
Monitor* monitor = MonitorManager::create_monitor(obj->name(), module, &obj->m_parameters);
|
|
|
|
|
if (monitor == NULL)
|
|
|
|
|
{
|
|
|
|
|
MXS_ERROR("Failed to create monitor '%s'.", obj->object());
|
|
|
|
|
MXS_ERROR("Failed to create monitor '%s'.", obj->name());
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -3784,7 +3784,7 @@ int create_new_monitor(CONFIG_CONTEXT* obj, std::set<std::string>& monitored_ser
|
|
|
|
|
*/
|
|
|
|
|
int create_new_listener(CONFIG_CONTEXT* obj)
|
|
|
|
|
{
|
|
|
|
|
auto protocol = obj->parameters.get_string(CN_PROTOCOL);
|
|
|
|
|
auto protocol = obj->m_parameters.get_string(CN_PROTOCOL);
|
|
|
|
|
mxb_assert(!protocol.empty());
|
|
|
|
|
|
|
|
|
|
if (const MXS_MODULE* mod = get_module(protocol.c_str(), MODULE_PROTOCOL))
|
|
|
|
@ -3800,32 +3800,32 @@ int create_new_listener(CONFIG_CONTEXT* obj)
|
|
|
|
|
|
|
|
|
|
int error_count = 0;
|
|
|
|
|
|
|
|
|
|
bool port_defined = obj->parameters.contains(CN_PORT);
|
|
|
|
|
bool socket_defined = obj->parameters.contains(CN_SOCKET);
|
|
|
|
|
bool port_defined = obj->m_parameters.contains(CN_PORT);
|
|
|
|
|
bool socket_defined = obj->m_parameters.contains(CN_SOCKET);
|
|
|
|
|
|
|
|
|
|
if (port_defined && socket_defined)
|
|
|
|
|
{
|
|
|
|
|
MXS_ERROR("Creation of listener '%s' failed because both 'socket' and 'port' "
|
|
|
|
|
"are defined. Only one of them is allowed.",
|
|
|
|
|
obj->object());
|
|
|
|
|
obj->name());
|
|
|
|
|
error_count++;
|
|
|
|
|
}
|
|
|
|
|
else if (!port_defined && !socket_defined)
|
|
|
|
|
{
|
|
|
|
|
MXS_ERROR("Listener '%s' is missing a required parameter. A Listener "
|
|
|
|
|
"must have a service, protocol and port (or socket) defined.",
|
|
|
|
|
obj->object());
|
|
|
|
|
obj->name());
|
|
|
|
|
error_count++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
auto address = obj->parameters.get_string(CN_ADDRESS);
|
|
|
|
|
Service* service = static_cast<Service*>(obj->parameters.get_service(CN_SERVICE));
|
|
|
|
|
auto address = obj->m_parameters.get_string(CN_ADDRESS);
|
|
|
|
|
Service* service = static_cast<Service*>(obj->m_parameters.get_service(CN_SERVICE));
|
|
|
|
|
mxb_assert(service);
|
|
|
|
|
|
|
|
|
|
// The conditionals just enforce defaults expected in the function.
|
|
|
|
|
auto port = port_defined ? obj->parameters.get_integer(CN_PORT) : 0;
|
|
|
|
|
auto socket = socket_defined ? obj->parameters.get_string(CN_SOCKET) : "";
|
|
|
|
|
auto port = port_defined ? obj->m_parameters.get_integer(CN_PORT) : 0;
|
|
|
|
|
auto socket = socket_defined ? obj->m_parameters.get_string(CN_SOCKET) : "";
|
|
|
|
|
|
|
|
|
|
// Remove this once maxadmin is removed
|
|
|
|
|
if (strcasecmp(protocol.c_str(), "maxscaled") == 0 && socket_defined
|
|
|
|
@ -3838,10 +3838,10 @@ int create_new_listener(CONFIG_CONTEXT* obj)
|
|
|
|
|
if (auto l = service_find_listener(service, socket, address, port))
|
|
|
|
|
{
|
|
|
|
|
string socket_type = socket_defined ? "socket" : "port";
|
|
|
|
|
string socket_definition = socket_defined ? socket : obj->parameters.get_string(CN_PORT);
|
|
|
|
|
string socket_definition = socket_defined ? socket : obj->m_parameters.get_string(CN_PORT);
|
|
|
|
|
MXS_ERROR("Creation of listener '%s' for service '%s' failed, because "
|
|
|
|
|
"listener '%s' already listens on the %s %s.",
|
|
|
|
|
obj->object(),
|
|
|
|
|
obj->name(),
|
|
|
|
|
service->name(),
|
|
|
|
|
l->name(),
|
|
|
|
|
socket_type.c_str(),
|
|
|
|
@ -3849,21 +3849,21 @@ int create_new_listener(CONFIG_CONTEXT* obj)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto protocol = obj->parameters.get_string(CN_PROTOCOL);
|
|
|
|
|
auto protocol = obj->m_parameters.get_string(CN_PROTOCOL);
|
|
|
|
|
SSL_LISTENER* ssl_info = NULL;
|
|
|
|
|
|
|
|
|
|
if (!config_create_ssl(obj->object(), &obj->parameters, true, &ssl_info))
|
|
|
|
|
if (!config_create_ssl(obj->name(), &obj->m_parameters, true, &ssl_info))
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// These two values being NULL trigger the loading of the default
|
|
|
|
|
// authenticators that are specific to each protocol module
|
|
|
|
|
auto authenticator = obj->parameters.get_string(CN_AUTHENTICATOR);
|
|
|
|
|
auto authenticator_options = obj->parameters.get_string(CN_AUTHENTICATOR_OPTIONS);
|
|
|
|
|
auto authenticator = obj->m_parameters.get_string(CN_AUTHENTICATOR);
|
|
|
|
|
auto authenticator_options = obj->m_parameters.get_string(CN_AUTHENTICATOR_OPTIONS);
|
|
|
|
|
int net_port = socket_defined ? 0 : port;
|
|
|
|
|
|
|
|
|
|
auto listener = Listener::create(service, obj->object(), protocol, socket_defined ? socket : address,
|
|
|
|
|
auto listener = Listener::create(service, obj->name(), protocol, socket_defined ? socket : address,
|
|
|
|
|
net_port, authenticator, authenticator_options, ssl_info);
|
|
|
|
|
|
|
|
|
|
if (!listener)
|
|
|
|
@ -3883,7 +3883,7 @@ int create_new_listener(CONFIG_CONTEXT* obj)
|
|
|
|
|
int create_new_filter(CONFIG_CONTEXT* obj)
|
|
|
|
|
{
|
|
|
|
|
int error_count = 0;
|
|
|
|
|
auto module_str = obj->parameters.get_string(CN_MODULE);
|
|
|
|
|
auto module_str = obj->m_parameters.get_string(CN_MODULE);
|
|
|
|
|
mxb_assert(!module_str.empty());
|
|
|
|
|
const char* module = module_str.c_str();
|
|
|
|
|
|
|
|
|
@ -3891,10 +3891,10 @@ int create_new_filter(CONFIG_CONTEXT* obj)
|
|
|
|
|
{
|
|
|
|
|
config_add_defaults(obj, mod->parameters);
|
|
|
|
|
|
|
|
|
|
if (!filter_alloc(obj->object(), module, &obj->parameters))
|
|
|
|
|
if (!filter_alloc(obj->name(), module, &obj->m_parameters))
|
|
|
|
|
{
|
|
|
|
|
MXS_ERROR("Failed to create filter '%s'. Memory allocation failed.",
|
|
|
|
|
obj->object());
|
|
|
|
|
obj->name());
|
|
|
|
|
error_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -3909,7 +3909,7 @@ int create_new_filter(CONFIG_CONTEXT* obj)
|
|
|
|
|
|
|
|
|
|
bool config_have_required_ssl_params(CONFIG_CONTEXT* obj)
|
|
|
|
|
{
|
|
|
|
|
MXS_CONFIG_PARAMETER* param = &obj->parameters;
|
|
|
|
|
MXS_CONFIG_PARAMETER* param = &obj->m_parameters;
|
|
|
|
|
return param->contains(CN_SSL)
|
|
|
|
|
&& param->contains(CN_SSL_KEY)
|
|
|
|
|
&& param->contains(CN_SSL_CERT)
|
|
|
|
@ -4033,12 +4033,12 @@ static bool config_contains_type(const CONFIG_CONTEXT* ctx, const char* name, co
|
|
|
|
|
{
|
|
|
|
|
while (ctx)
|
|
|
|
|
{
|
|
|
|
|
if (strcmp(ctx->object(), name) == 0 && type == ctx->parameters.get_string(CN_TYPE))
|
|
|
|
|
if (strcmp(ctx->name(), name) == 0 && type == ctx->m_parameters.get_string(CN_TYPE))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx = ctx->next;
|
|
|
|
|
ctx = ctx->m_next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|