summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorSara Golemon <sara.golemon@mongodb.com>2018-04-10 16:24:53 -0400
committerSara Golemon <sara.golemon@mongodb.com>2018-04-18 17:25:40 -0400
commit14d03a79f55d69ccdd27bb4a08906a4be5eb4a8e (patch)
treefb4eeea5ea2be69bd93e9050ede9ebcad1aefe92 /src/mongo
parentd31c1e77117668ae11a967311d251ad0a4f26d01 (diff)
downloadmongo-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.txt2
-rw-r--r--src/mongo/db/auth/role_graph_builtin_roles.cpp4
-rw-r--r--src/mongo/db/free_mon/SConscript9
-rw-r--r--src/mongo/db/free_mon/free_mon_commands.cpp141
-rw-r--r--src/mongo/db/free_mon/free_mon_commands_stub.cpp87
-rw-r--r--src/mongo/db/free_mon/free_mon_controller.cpp6
-rw-r--r--src/mongo/db/free_mon/free_mon_controller.h11
-rw-r--r--src/mongo/db/free_mon/free_mon_message.h5
-rw-r--r--src/mongo/db/free_mon/free_mon_mongod.cpp1
-rw-r--r--src/mongo/db/free_mon/free_mon_processor.cpp4
-rw-r--r--src/mongo/db/free_mon/free_mon_storage.cpp13
-rw-r--r--src/mongo/db/free_mon/free_mon_storage.h7
-rw-r--r--src/mongo/s/commands/SConscript2
-rw-r--r--src/mongo/s/commands/cluster_set_free_monitoring.cpp73
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