diff options
author | Sara Golemon <sara.golemon@mongodb.com> | 2018-04-10 16:24:53 -0400 |
---|---|---|
committer | Sara Golemon <sara.golemon@mongodb.com> | 2018-04-18 17:25:40 -0400 |
commit | 14d03a79f55d69ccdd27bb4a08906a4be5eb4a8e (patch) | |
tree | fb4eeea5ea2be69bd93e9050ede9ebcad1aefe92 /src/mongo | |
parent | d31c1e77117668ae11a967311d251ad0a4f26d01 (diff) | |
download | mongo-14d03a79f55d69ccdd27bb4a08906a4be5eb4a8e.tar.gz |
SERVER-34230 Add ActionType and Commands for Free Monitoring
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/auth/action_types.txt | 2 | ||||
-rw-r--r-- | src/mongo/db/auth/role_graph_builtin_roles.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/free_mon/SConscript | 9 | ||||
-rw-r--r-- | src/mongo/db/free_mon/free_mon_commands.cpp | 141 | ||||
-rw-r--r-- | src/mongo/db/free_mon/free_mon_commands_stub.cpp | 87 | ||||
-rw-r--r-- | src/mongo/db/free_mon/free_mon_controller.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/free_mon/free_mon_controller.h | 11 | ||||
-rw-r--r-- | src/mongo/db/free_mon/free_mon_message.h | 5 | ||||
-rw-r--r-- | src/mongo/db/free_mon/free_mon_mongod.cpp | 1 | ||||
-rw-r--r-- | src/mongo/db/free_mon/free_mon_processor.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/free_mon/free_mon_storage.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/free_mon/free_mon_storage.h | 7 | ||||
-rw-r--r-- | src/mongo/s/commands/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_set_free_monitoring.cpp | 73 |
14 files changed, 360 insertions, 5 deletions
diff --git a/src/mongo/db/auth/action_types.txt b/src/mongo/db/auth/action_types.txt index b10bdf2c1c9..d641378e162 100644 --- a/src/mongo/db/auth/action_types.txt +++ b/src/mongo/db/auth/action_types.txt @@ -19,6 +19,7 @@ "changeOwnPassword", "changeOwnCustomData", "changeStream", +"checkFreeMonitoringStatus", "cleanupOrphaned", "closeAllDatabases", # Deprecated, needs to stay around for backwards compatibility "collMod", @@ -103,6 +104,7 @@ "serverStatus", "setAuthenticationRestriction", "setFeatureCompatibilityVersion", +"setFreeMonitoring", "setParameter", "shardCollection", # Not used for permissions checks, but to id the event in logs. "shardingState", diff --git a/src/mongo/db/auth/role_graph_builtin_roles.cpp b/src/mongo/db/auth/role_graph_builtin_roles.cpp index 79be5b05108..5b8cd34ea8f 100644 --- a/src/mongo/db/auth/role_graph_builtin_roles.cpp +++ b/src/mongo/db/auth/role_graph_builtin_roles.cpp @@ -182,6 +182,7 @@ MONGO_INITIALIZER(AuthorizationBuiltinRoles)(InitializerContext* context) { // clusterMonitor role actions that target the cluster resource clusterMonitorRoleClusterActions + << ActionType::checkFreeMonitoringStatus << ActionType::connPoolStats << ActionType::getCmdLineOpts << ActionType::getLog @@ -250,7 +251,8 @@ MONGO_INITIALIZER(AuthorizationBuiltinRoles)(InitializerContext* context) { << ActionType::listShards // clusterMonitor gets this also << ActionType::flushRouterConfig // hostManager gets this also << ActionType::cleanupOrphaned - << ActionType::setFeatureCompatibilityVersion; + << ActionType::setFeatureCompatibilityVersion + << ActionType::setFreeMonitoring; clusterManagerRoleDatabaseActions << ActionType::splitChunk diff --git a/src/mongo/db/free_mon/SConscript b/src/mongo/db/free_mon/SConscript index c13649b2f37..3047553317a 100644 --- a/src/mongo/db/free_mon/SConscript +++ b/src/mongo/db/free_mon/SConscript @@ -32,6 +32,7 @@ if get_option("enable-free-mon") == "on": fmEnv.Library( target='free_mon_mongod', source=[ + 'free_mon_commands.cpp', 'free_mon_mongod.cpp', 'free_mon_options.cpp', 'http_client_curl.cpp' if not env.TargetOSIs('windows') else 'http_client_winhttp.cpp', @@ -52,8 +53,16 @@ else: fmEnv.Library( target='free_mon_mongod', source=[ + 'free_mon_commands_stub.cpp', 'free_mon_stub.cpp', ], + LIBDEPS_PRIVATE=[ + 'free_mon', + '$BUILD_DIR/mongo/base', + '$BUILD_DIR/mongo/db/commands', + '$BUILD_DIR/mongo/db/auth/authcore', + '$BUILD_DIR/mongo/db/auth/authprivilege', + ], ) diff --git a/src/mongo/db/free_mon/free_mon_commands.cpp b/src/mongo/db/free_mon/free_mon_commands.cpp new file mode 100644 index 00000000000..1e78bc5b768 --- /dev/null +++ b/src/mongo/db/free_mon/free_mon_commands.cpp @@ -0,0 +1,141 @@ +/** + * Copyright (C) 2018 MongoDB 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 <http://www.gnu.org/licenses/>. + * + * 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. + */ + +#include "mongo/platform/basic.h" + +#include "mongo/db/auth/authorization_session.h" +#include "mongo/db/commands.h" +#include "mongo/db/free_mon/free_mon_commands_gen.h" +#include "mongo/db/free_mon/free_mon_controller.h" +#include "mongo/db/free_mon/free_mon_storage.h" + +namespace mongo { + +namespace { + +const auto kRegisterSyncTimeout = Milliseconds{100}; + +/** + * Indicates the current status of Free Monitoring. + */ +class GetFreeMonitoringStatusCommand : public BasicCommand { +public: + GetFreeMonitoringStatusCommand() : BasicCommand("getFreeMonitoringStatus") {} + + AllowedOnSecondary secondaryAllowed(ServiceContext*) const final { + return AllowedOnSecondary::kAlways; + } + + bool supportsWriteConcern(const BSONObj& cmd) const final { + return false; + } + + std::string help() const final { + return "Indicates free monitoring status"; + } + + Status checkAuthForCommand(Client* client, + const std::string& dbname, + const BSONObj& cmdObj) const final { + if (!AuthorizationSession::get(client)->isAuthorizedForActionsOnResource( + ResourcePattern::forClusterResource(), ActionType::checkFreeMonitoringStatus)) { + return Status(ErrorCodes::Unauthorized, "Unauthorized"); + } + return Status::OK(); + } + + bool run(OperationContext* opCtx, + const std::string& dbname, + const BSONObj& cmdObj, + BSONObjBuilder& result) final { + // Command has no members, invoke the parser to confirm that. + IDLParserErrorContext ctx("getFreeMonitoringStatus"); + GetFreeMonitoringStatus::parse(ctx, cmdObj); + + FreeMonStorage::getStatus(opCtx, &result); + return true; + } +} getFreeMonitoringStatusCommand; + +/** + * Enables or disables Free Monitoring service. + */ +class SetFreeMonitoringCommand : public BasicCommand { +public: + SetFreeMonitoringCommand() : BasicCommand("setFreeMonitoring") {} + + AllowedOnSecondary secondaryAllowed(ServiceContext*) const final { + return AllowedOnSecondary::kNever; + } + + bool supportsWriteConcern(const BSONObj& cmd) const final { + return false; + } + + std::string help() const final { + return "enable or disable Free Monitoring"; + } + + Status checkAuthForCommand(Client* client, + const std::string& dbname, + const BSONObj& cmdObj) const final { + if (!AuthorizationSession::get(client)->isAuthorizedForActionsOnResource( + ResourcePattern::forClusterResource(), ActionType::setFreeMonitoring)) { + return Status(ErrorCodes::Unauthorized, "Unauthorized"); + } + return Status::OK(); + } + + bool run(OperationContext* opCtx, + const std::string& dbname, + const BSONObj& cmdObj, + BSONObjBuilder& result) final { + IDLParserErrorContext ctx("setFreeMonitoring"); + auto cmd = SetFreeMonitoring::parse(ctx, cmdObj); + + auto* controller = FreeMonController::get(opCtx->getServiceContext()); + boost::optional<Status> optStatus = boost::none; + if (cmd.getAction() == SetFreeMonActionEnum::enable) { + optStatus = controller->registerServerCommand(kRegisterSyncTimeout); + } else { + optStatus = controller->unregisterServerCommand(); + } + + if (optStatus) { + // Completed within timeout. + return CommandHelpers::appendCommandStatus(result, *optStatus); + } else { + // Pending operation. + return CommandHelpers::appendCommandStatus(result, Status::OK()); + } + } + +} setFreeMonitoringCmd; + +} // namespace +} // namespace mongo diff --git a/src/mongo/db/free_mon/free_mon_commands_stub.cpp b/src/mongo/db/free_mon/free_mon_commands_stub.cpp new file mode 100644 index 00000000000..77538997889 --- /dev/null +++ b/src/mongo/db/free_mon/free_mon_commands_stub.cpp @@ -0,0 +1,87 @@ +/** + * Copyright (C) 2018 MongoDB 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 <http://www.gnu.org/licenses/>. + * + * 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. + */ + +#include "mongo/platform/basic.h" + +#include "mongo/db/auth/authorization_session.h" +#include "mongo/db/commands.h" +#include "mongo/db/free_mon/free_mon_commands_gen.h" + +namespace mongo { + +namespace { + +/** + * Indicates the current status of Free Monitoring. + * + * Note that this file is only built when --enable-free-mon=off + * and it will return a static result of {status:"disabled"}. + */ +class GetFreeMonitoringStatusCommandStub : public BasicCommand { +public: + GetFreeMonitoringStatusCommandStub() : BasicCommand("getFreeMonitoringStatus") {} + + AllowedOnSecondary secondaryAllowed(ServiceContext*) const final { + return AllowedOnSecondary::kAlways; + } + + bool supportsWriteConcern(const BSONObj& cmd) const final { + return false; + } + + std::string help() const final { + return "Indicates free monitoring status"; + } + + Status checkAuthForCommand(Client* client, + const std::string& dbname, + const BSONObj& cmdObj) const final { + if (!AuthorizationSession::get(client)->isAuthorizedForActionsOnResource( + ResourcePattern::forClusterResource(), ActionType::checkFreeMonitoringStatus)) { + return Status(ErrorCodes::Unauthorized, "Unauthorized"); + } + return Status::OK(); + } + + bool run(OperationContext* opCtx, + const std::string& dbname, + const BSONObj& cmdObj, + BSONObjBuilder& result) final { + // Command has no members, invoke the parser to confirm that. + IDLParserErrorContext ctx("getFreeMonitoringStatus"); + GetFreeMonitoringStatus::parse(ctx, cmdObj); + + result.append("state", "disabled"); + result.append("message", + "Free Monitoring support is not available in this build of MongoDB"); + return true; + } +} getFreeMonitoringStatusCommand; + +} // namespace +} // namespace mongo diff --git a/src/mongo/db/free_mon/free_mon_controller.cpp b/src/mongo/db/free_mon/free_mon_controller.cpp index f8d17816db7..a1fcb4fd214 100644 --- a/src/mongo/db/free_mon/free_mon_controller.cpp +++ b/src/mongo/db/free_mon/free_mon_controller.cpp @@ -77,6 +77,11 @@ boost::optional<Status> FreeMonController::registerServerCommand(Milliseconds ti return Status::OK(); } +Status FreeMonController::unregisterServerCommand() { + _enqueue(FreeMonMessage::createNow(FreeMonMessageType::UnregisterCommand)); + return Status::OK(); +} + void FreeMonController::_enqueue(std::shared_ptr<FreeMonMessage> msg) { { stdx::lock_guard<stdx::mutex> lock(_mutex); @@ -139,5 +144,4 @@ void FreeMonController::stop() { _state = State::kDone; } - } // namespace mongo diff --git a/src/mongo/db/free_mon/free_mon_controller.h b/src/mongo/db/free_mon/free_mon_controller.h index 87c0ebb62b8..69c1f811934 100644 --- a/src/mongo/db/free_mon/free_mon_controller.h +++ b/src/mongo/db/free_mon/free_mon_controller.h @@ -97,10 +97,15 @@ public: */ boost::optional<Status> registerServerCommand(Milliseconds timeout); - // TODO - add these methods - // Status deregisterServerCommand(Milliseconds timeout); + /** + * Stop registration of mongod with remote service. + * + * As with registerServerCommand() above, but undoes registration. + * On complettion of this command, no further metrics will be transmitted. + */ + Status unregisterServerCommand(); - // void getStatus(BSONObjBuilder* builder); + // TODO - add these methods // void getServerStatus(BSONObjBuilder* builder); // void notifyObserver(const BSONObj& doc); diff --git a/src/mongo/db/free_mon/free_mon_message.h b/src/mongo/db/free_mon/free_mon_message.h index 2ed3b11e9c8..b7b514ee775 100644 --- a/src/mongo/db/free_mon/free_mon_message.h +++ b/src/mongo/db/free_mon/free_mon_message.h @@ -65,6 +65,11 @@ enum class FreeMonMessageType { */ AsyncRegisterFail, + /** + * Unregister server from server command. + */ + UnregisterCommand, + // TODO - add metrics messages // MetricsCollect - Cloud wants the "wait" time to calculated when the message processing // starts, not ends diff --git a/src/mongo/db/free_mon/free_mon_mongod.cpp b/src/mongo/db/free_mon/free_mon_mongod.cpp index 9d41ba96d38..4201d4e39ba 100644 --- a/src/mongo/db/free_mon/free_mon_mongod.cpp +++ b/src/mongo/db/free_mon/free_mon_mongod.cpp @@ -57,6 +57,7 @@ #include "mongo/db/server_parameters.h" #include "mongo/db/service_context.h" #include "mongo/executor/network_interface_factory.h" +#include "mongo/rpc/object_check.h" #include "mongo/util/assert_util.h" #include "mongo/util/concurrency/thread_pool.h" #include "mongo/util/future.h" diff --git a/src/mongo/db/free_mon/free_mon_processor.cpp b/src/mongo/db/free_mon/free_mon_processor.cpp index 2713e19be32..16097b42a77 100644 --- a/src/mongo/db/free_mon/free_mon_processor.cpp +++ b/src/mongo/db/free_mon/free_mon_processor.cpp @@ -144,6 +144,10 @@ void FreeMonProcessor::run() { item.get().get())); break; } + case FreeMonMessageType::UnregisterCommand: { + doUnregister(client); + break; + } default: MONGO_UNREACHABLE; } diff --git a/src/mongo/db/free_mon/free_mon_storage.cpp b/src/mongo/db/free_mon/free_mon_storage.cpp index 627ad076424..d7ee1499e37 100644 --- a/src/mongo/db/free_mon/free_mon_storage.cpp +++ b/src/mongo/db/free_mon/free_mon_storage.cpp @@ -132,4 +132,17 @@ boost::optional<BSONObj> FreeMonStorage::readClusterManagerState(OperationContex return swObj.getValue(); } +void FreeMonStorage::getStatus(OperationContext* opCtx, BSONObjBuilder* builder) { + auto state = read(opCtx); + if (!state) { + builder->append("state", "undecided"); + return; + } + + builder->append("state", StorageState_serializer(state->getState())); + builder->append("message", state->getMessage()); + builder->append("url", state->getInformationalURL()); + builder->append("userReminder", state->getUserReminder()); +} + } // namespace mongo diff --git a/src/mongo/db/free_mon/free_mon_storage.h b/src/mongo/db/free_mon/free_mon_storage.h index fd7d81e68bf..cc2fc47ff6d 100644 --- a/src/mongo/db/free_mon/free_mon_storage.h +++ b/src/mongo/db/free_mon/free_mon_storage.h @@ -62,6 +62,13 @@ public: * Returns nothing if there are more then one document or it does not exist. */ static boost::optional<BSONObj> readClusterManagerState(OperationContext* opCtx); + + /** + * Populate a BSON object with the current status of FreeMonitoring. + * This status object will be suitable for return to a caller + * invoking the {getFreeMonitoringStatus:1} command. + */ + static void getStatus(OperationContext* opCtx, BSONObjBuilder* builder); }; } // namespace mongo diff --git a/src/mongo/s/commands/SConscript b/src/mongo/s/commands/SConscript index 51c3358732d..c84f1a20091 100644 --- a/src/mongo/s/commands/SConscript +++ b/src/mongo/s/commands/SConscript @@ -1,6 +1,7 @@ # -*- mode: python -*- Import("env") +Import("get_option") env = env.Clone() @@ -77,6 +78,7 @@ env.Library( 'cluster_reset_error_cmd.cpp', 'cluster_restart_catalog_command.cpp', 'cluster_set_feature_compatibility_version_cmd.cpp', + 'cluster_set_free_monitoring.cpp' if get_option("enable-free-mon") == 'on' else [], 'cluster_shard_collection_cmd.cpp', 'cluster_shutdown_cmd.cpp', 'cluster_split_cmd.cpp', diff --git a/src/mongo/s/commands/cluster_set_free_monitoring.cpp b/src/mongo/s/commands/cluster_set_free_monitoring.cpp new file mode 100644 index 00000000000..6a92763d81a --- /dev/null +++ b/src/mongo/s/commands/cluster_set_free_monitoring.cpp @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2018 MongoDB 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 <http://www.gnu.org/licenses/>. + * + * 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. + */ + +#include "mongo/platform/basic.h" + +#include "mongo/db/auth/authorization_session.h" +#include "mongo/db/commands.h" + +namespace mongo { +namespace { + +class ClusterSetFreeMonitoring : public BasicCommand { +public: + ClusterSetFreeMonitoring() : BasicCommand("setFreeMonitoring") {} + + AllowedOnSecondary secondaryAllowed(ServiceContext*) const final { + return AllowedOnSecondary::kNever; + } + + bool supportsWriteConcern(const BSONObj& cmd) const final { + return false; + } + + std::string help() const final { + return "setFreeMonitoring command must be run against mongod instances"; + } + + Status checkAuthForCommand(Client* client, + const std::string& dbname, + const BSONObj& cmdObj) const final { + if (!AuthorizationSession::get(client)->isAuthorizedForActionsOnResource( + ResourcePattern::forClusterResource(), ActionType::setFreeMonitoring)) { + return Status(ErrorCodes::Unauthorized, "Unauthorized"); + } + return Status::OK(); + } + + bool run(OperationContext* opCtx, + const std::string& dbname, + const BSONObj& cmdObj, + BSONObjBuilder& result) final { + return CommandHelpers::appendCommandStatus(result, {ErrorCodes::CommandFailed, help()}); + } + +} clusterSetFreeMonitoring; + +} // namespace +} // namespace mongo |