/**
* Copyright (C) 2013 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the GNU Affero General Public License in all respects
* for all of the code used other than as permitted herein. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you do not
* wish to do so, delete this exception statement from your version. If you
* delete this exception statement from all source files in the program,
* then also delete it in the license file.
*/
#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kSharding
#include "mongo/platform/basic.h"
#include "mongo/s/mongos_options.h"
#include
#include
#include
#include "mongo/base/status.h"
#include "mongo/base/status_with.h"
#include "mongo/bson/util/builder.h"
#include "mongo/config.h"
#include "mongo/db/server_options.h"
#include "mongo/db/server_options_helpers.h"
#include "mongo/s/version_mongos.h"
#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
#include "mongo/util/net/sock.h"
#include "mongo/util/net/ssl_options.h"
#include "mongo/util/options_parser/startup_options.h"
#include "mongo/util/startup_test.h"
#include "mongo/util/stringutils.h"
namespace mongo {
MongosGlobalParams mongosGlobalParams;
Status addMongosOptions(moe::OptionSection* options) {
moe::OptionSection general_options("General options");
Status ret = addGeneralServerOptions(&general_options);
if (!ret.isOK()) {
return ret;
}
#if defined(_WIN32)
moe::OptionSection windows_scm_options("Windows Service Control Manager options");
ret = addWindowsServerOptions(&windows_scm_options);
if (!ret.isOK()) {
return ret;
}
#endif
#ifdef MONGO_CONFIG_SSL
moe::OptionSection ssl_options("SSL options");
ret = addSSLServerOptions(&ssl_options);
if (!ret.isOK()) {
return ret;
}
#endif
moe::OptionSection sharding_options("Sharding options");
sharding_options.addOptionChaining("sharding.configDB",
"configdb",
moe::String,
"Connection string for communicating with config servers:\n"
"/,,[...]");
sharding_options.addOptionChaining(
"replication.localPingThresholdMs",
"localThreshold",
moe::Int,
"ping time (in ms) for a node to be considered local (default 15ms)");
sharding_options.addOptionChaining("test", "test", moe::Switch, "just run unit tests")
.setSources(moe::SourceAllLegacy);
sharding_options
.addOptionChaining("net.http.JSONPEnabled",
"jsonp",
moe::Switch,
"allow JSONP access via http (has security implications)")
.setSources(moe::SourceAllLegacy);
sharding_options
.addOptionChaining("noscripting", "noscripting", moe::Switch, "disable scripting engine")
.setSources(moe::SourceAllLegacy);
options->addSection(general_options);
#if defined(_WIN32)
options->addSection(windows_scm_options);
#endif
options->addSection(sharding_options);
#ifdef MONGO_CONFIG_SSL
options->addSection(ssl_options);
#endif
return Status::OK();
}
void printMongosHelp(const moe::OptionSection& options) {
std::cout << options.helpString() << std::endl;
};
bool handlePreValidationMongosOptions(const moe::Environment& params,
const std::vector& args) {
if (params.count("help") && params["help"].as() == true) {
printMongosHelp(moe::startupOptions);
return false;
}
if (params.count("version") && params["version"].as() == true) {
printShardingVersionInfo(true);
return false;
}
if (params.count("test") && params["test"].as() == true) {
::mongo::logger::globalLogDomain()->setMinimumLoggedSeverity(
::mongo::logger::LogSeverity::Debug(5));
StartupTest::runTests();
return false;
}
return true;
}
Status validateMongosOptions(const moe::Environment& params) {
Status ret = validateServerOptions(params);
if (!ret.isOK()) {
return ret;
}
return Status::OK();
}
Status canonicalizeMongosOptions(moe::Environment* params) {
Status ret = canonicalizeServerOptions(params);
if (!ret.isOK()) {
return ret;
}
#ifdef MONGO_CONFIG_SSL
ret = canonicalizeSSLServerOptions(params);
if (!ret.isOK()) {
return ret;
}
#endif
return Status::OK();
}
Status storeMongosOptions(const moe::Environment& params) {
Status ret = storeServerOptions(params);
if (!ret.isOK()) {
return ret;
}
if (params.count("net.port")) {
int port = params["net.port"].as();
if (port <= 0 || port > 65535) {
return Status(ErrorCodes::BadValue, "error: port number must be between 1 and 65535");
}
}
if (params.count("replication.localPingThresholdMs")) {
serverGlobalParams.defaultLocalThresholdMillis =
params["replication.localPingThresholdMs"].as();
}
if (params.count("net.http.JSONPEnabled")) {
serverGlobalParams.jsonp = params["net.http.JSONPEnabled"].as();
}
if (params.count("noscripting")) {
// This option currently has no effect for mongos
}
if (!params.count("sharding.configDB")) {
return Status(ErrorCodes::BadValue, "error: no args for --configdb");
}
std::string configdbString = params["sharding.configDB"].as();
auto configdbConnectionString = ConnectionString::parse(configdbString);
if (!configdbConnectionString.isOK()) {
return configdbConnectionString.getStatus();
}
if (configdbConnectionString.getValue().type() != ConnectionString::SET) {
return Status(ErrorCodes::BadValue,
str::stream() << "configdb supports only replica set connection string");
}
std::vector seedServers;
bool resolvedSomeSeedSever = false;
for (const auto& host : configdbConnectionString.getValue().getServers()) {
seedServers.push_back(host);
if (!seedServers.back().hasPort()) {
seedServers.back() = HostAndPort{host.host(), ServerGlobalParams::ConfigServerPort};
}
if (!hostbyname(seedServers.back().host().c_str()).empty()) {
resolvedSomeSeedSever = true;
}
}
if (!resolvedSomeSeedSever) {
if (!hostbyname(configdbConnectionString.getValue().getSetName().c_str()).empty()) {
warning() << "The replica set name \""
<< escape(configdbConnectionString.getValue().getSetName())
<< "\" resolves as a host name, but none of the servers in the seed list do. "
"Did you reverse the replica set name and the seed list in "
<< escape(configdbConnectionString.getValue().toString()) << "?";
}
}
mongosGlobalParams.configdbs =
ConnectionString{configdbConnectionString.getValue().type(),
seedServers,
configdbConnectionString.getValue().getSetName()};
if (mongosGlobalParams.configdbs.getServers().size() < 3) {
warning() << "Running a sharded cluster with fewer than 3 config servers should only be "
"done for testing purposes and is not recommended for production.";
}
return Status::OK();
}
} // namespace mongo