diff options
-rw-r--r-- | jstests/noPassthrough/cluster_explain_commands_not_supported.js | 87 | ||||
-rw-r--r-- | jstests/noPassthrough/cluster_explain_commands_require_cluster_node.js | 37 | ||||
-rw-r--r-- | src/mongo/db/s/cluster_count_cmd_d.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/s/cluster_find_cmd_d.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/s/cluster_pipeline_cmd_d.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/s/cluster_write_cmd_d.cpp | 14 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_count_cmd.h | 2 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_count_cmd_s.cpp | 4 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_find_cmd.h | 2 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_find_cmd_s.cpp | 4 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_pipeline_cmd.h | 2 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_pipeline_cmd_s.cpp | 4 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_write_cmd.cpp | 2 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_write_cmd.h | 13 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_write_cmd_s.cpp | 12 |
15 files changed, 157 insertions, 41 deletions
diff --git a/jstests/noPassthrough/cluster_explain_commands_not_supported.js b/jstests/noPassthrough/cluster_explain_commands_not_supported.js new file mode 100644 index 00000000000..3aa315382e3 --- /dev/null +++ b/jstests/noPassthrough/cluster_explain_commands_not_supported.js @@ -0,0 +1,87 @@ +/** + * Verify the explaining "cluster" versions of commands is not supported on any mongod + * + * @tags: [ + * requires_replication, + * requires_sharding, + * ] + */ +(function() { +"use strict"; + +const kDbName = "cluster_explain_commands"; +const kCollName = "bar"; + +const clusterCommandsCases = [ + {cmd: {explain: {clusterAggregate: kCollName, pipeline: [{$match: {}}], cursor: {}}}}, + {cmd: {explain: {clusterCount: "x"}}}, + {cmd: {explain: {clusterFind: kCollName}}}, + {cmd: {explain: {clusterInsert: kCollName, documents: [{x: 1}]}}}, + {cmd: {explain: {clusterUpdate: kCollName, updates: [{q: {doesNotExist: 1}, u: {x: 1}}]}}}, + {cmd: {explain: {clusterDelete: `${kCollName}`, deletes: [{q: {}, limit: 1}]}}} +]; + +function runTestCaseExpectFail(conn, testCase, code) { + assert.commandFailedWithCode( + conn.getDB(kDbName).runCommand(testCase.cmd), code, tojson(testCase.cmd)); +} + +// +// Cluster explain commands not supported on standalone mongods +// +{ + const standalone = MongoRunner.runMongod({}); + assert(standalone); + + for (let testCase of clusterCommandsCases) { + runTestCaseExpectFail(standalone, testCase, ErrorCodes.CommandNotSupported); + } + + MongoRunner.stopMongod(standalone); +} + +// +// Cluster explain commands not supported on replica set mongods +// +{ + const rst = new ReplSetTest({nodes: 1}); + rst.startSet(); + rst.initiate(); + + for (let testCase of clusterCommandsCases) { + runTestCaseExpectFail(rst.getPrimary(), testCase, ErrorCodes.CommandNotSupported); + } + + rst.stopSet(); +} + +{ + const st = new ShardingTest({mongos: 1, shards: 1, config: 1}); + + // + // Cluster explain commands do not exist on mongos. + // + + for (let testCase of clusterCommandsCases) { + runTestCaseExpectFail(st.s, testCase, ErrorCodes.CommandNotFound); + } + + // + // Cluster explain commands are not supported on a config server node. + // + + for (let testCase of clusterCommandsCases) { + runTestCaseExpectFail(st.configRS.getPrimary(), testCase, ErrorCodes.CommandNotSupported); + } + + // + // Cluster explain commands are not supported sharding enabled shardsvr. + // + + for (let testCase of clusterCommandsCases) { + runTestCaseExpectFail(st.rs0.getPrimary(), testCase, ErrorCodes.CommandNotSupported); + } + + st.stop(); +} +}()); diff --git a/jstests/noPassthrough/cluster_explain_commands_require_cluster_node.js b/jstests/noPassthrough/cluster_explain_commands_require_cluster_node.js deleted file mode 100644 index 5e009345d80..00000000000 --- a/jstests/noPassthrough/cluster_explain_commands_require_cluster_node.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Verify the explaining "cluster" versions of commands is rejected on a non shardsvr mongod. - * - * @tags: [ - * requires_replication, - * ] - */ -(function() { -"use strict"; - -const kDbName = "cluster_explain_commands"; -const kCollName = "bar"; -const rst = new ReplSetTest({nodes: 1}); -rst.startSet(); -rst.initiate(); - -const clusterCommandsCases = [ - {cmd: {explain: {clusterAggregate: kCollName, pipeline: [{$match: {}}], cursor: {}}}}, - {cmd: {explain: {clusterCount: "x"}}}, - {cmd: {explain: {clusterDelete: kCollName, deletes: [{q: {}, limit: 1}]}}}, - {cmd: {explain: {clusterFind: kCollName}}}, - {cmd: {explain: {clusterInsert: kCollName, documents: [{x: 1}]}}}, - {cmd: {explain: {clusterUpdate: kCollName, updates: [{q: {doesNotExist: 1}, u: {x: 1}}]}}}, - {cmd: {explain: {clusterDelete: `${kCollName}`, deletes: [{q: {}, limit: 1}]}}} -]; - -function runTestCaseExpectFail(conn, testCase, code) { - assert.commandFailedWithCode( - conn.getDB(kDbName).runCommand(testCase.cmd), code, tojson(testCase.cmd)); -} - -for (let testCase of clusterCommandsCases) { - runTestCaseExpectFail(rst.getPrimary(), testCase, ErrorCodes.ShardingStateNotInitialized); -} - -rst.stopSet(); -}()); diff --git a/src/mongo/db/s/cluster_count_cmd_d.cpp b/src/mongo/db/s/cluster_count_cmd_d.cpp index 27c64148cc9..a593a299b4f 100644 --- a/src/mongo/db/s/cluster_count_cmd_d.cpp +++ b/src/mongo/db/s/cluster_count_cmd_d.cpp @@ -62,6 +62,11 @@ struct ClusterCountCmdD { // which triggers an invariant, so only shard servers can run this. uassertStatusOK(ShardingState::get(opCtx)->canAcceptShardedCommands()); } + + static void checkCanExplainHere(OperationContext* opCtx) { + uasserted(ErrorCodes::CommandNotSupported, + "Cannot explain a cluster count command on a mongod"); + } }; ClusterCountCmdBase<ClusterCountCmdD> clusterCountCmdD; diff --git a/src/mongo/db/s/cluster_find_cmd_d.cpp b/src/mongo/db/s/cluster_find_cmd_d.cpp index e97f07b70e7..e98315c06ad 100644 --- a/src/mongo/db/s/cluster_find_cmd_d.cpp +++ b/src/mongo/db/s/cluster_find_cmd_d.cpp @@ -61,6 +61,11 @@ struct ClusterFindCmdD { // which triggers an invariant, so only shard servers can run this. uassertStatusOK(ShardingState::get(opCtx)->canAcceptShardedCommands()); } + + static void checkCanExplainHere(OperationContext* opCtx) { + uasserted(ErrorCodes::CommandNotSupported, + "Cannot explain a cluster find command on a mongod"); + } }; ClusterFindCmdBase<ClusterFindCmdD> clusterFindCmdD; diff --git a/src/mongo/db/s/cluster_pipeline_cmd_d.cpp b/src/mongo/db/s/cluster_pipeline_cmd_d.cpp index 437e7418355..1b3eed4242a 100644 --- a/src/mongo/db/s/cluster_pipeline_cmd_d.cpp +++ b/src/mongo/db/s/cluster_pipeline_cmd_d.cpp @@ -61,6 +61,11 @@ struct ClusterPipelineCommandD { uassertStatusOK(ShardingState::get(opCtx)->canAcceptShardedCommands()); } + static void checkCanExplainHere(OperationContext* opCtx) { + uasserted(ErrorCodes::CommandNotSupported, + "Cannot explain a cluster aggregate command on a mongod"); + } + static AggregateCommandRequest parseAggregationRequest( OperationContext* opCtx, const OpMsgRequest& opMsgRequest, diff --git a/src/mongo/db/s/cluster_write_cmd_d.cpp b/src/mongo/db/s/cluster_write_cmd_d.cpp index c8f75d69e15..66167ab2b30 100644 --- a/src/mongo/db/s/cluster_write_cmd_d.cpp +++ b/src/mongo/db/s/cluster_write_cmd_d.cpp @@ -57,6 +57,11 @@ struct ClusterInsertCmdD { // which triggers an invariant, so only shard servers can run this. uassertStatusOK(ShardingState::get(opCtx)->canAcceptShardedCommands()); } + + static void checkCanExplainHere(OperationContext* opCtx) { + uasserted(ErrorCodes::CommandNotSupported, + "Cannot explain a cluster insert command on a mongod"); + } }; ClusterInsertCmdBase<ClusterInsertCmdD> clusterInsertCmdD; @@ -83,6 +88,10 @@ struct ClusterUpdateCmdD { // which triggers an invariant, so only shard servers can run this. uassertStatusOK(ShardingState::get(opCtx)->canAcceptShardedCommands()); } + + static void checkCanExplainHere(OperationContext* opCtx) { + uasserted(ErrorCodes::CommandNotSupported, "Explain on a clusterDelete is not supported"); + } }; ClusterUpdateCmdBase<ClusterUpdateCmdD> clusterUpdateCmdD; @@ -109,6 +118,11 @@ struct ClusterDeleteCmdD { // which triggers an invariant, so only shard servers can run this. uassertStatusOK(ShardingState::get(opCtx)->canAcceptShardedCommands()); } + + static void checkCanExplainHere(OperationContext* opCtx) { + uasserted(ErrorCodes::CommandNotSupported, + "Cannot explain a cluster delete command on a mongod"); + } }; ClusterDeleteCmdBase<ClusterDeleteCmdD> clusterDeleteCmdD; diff --git a/src/mongo/s/commands/cluster_count_cmd.h b/src/mongo/s/commands/cluster_count_cmd.h index d90421f550f..aa10b33e442 100644 --- a/src/mongo/s/commands/cluster_count_cmd.h +++ b/src/mongo/s/commands/cluster_count_cmd.h @@ -209,7 +209,7 @@ public: const OpMsgRequest& request, ExplainOptions::Verbosity verbosity, rpc::ReplyBuilderInterface* result) const override { - Impl::checkCanRunHere(opCtx); + Impl::checkCanExplainHere(opCtx); const BSONObj& cmdObj = request.body; diff --git a/src/mongo/s/commands/cluster_count_cmd_s.cpp b/src/mongo/s/commands/cluster_count_cmd_s.cpp index 4226d06a189..3bdf689385b 100644 --- a/src/mongo/s/commands/cluster_count_cmd_s.cpp +++ b/src/mongo/s/commands/cluster_count_cmd_s.cpp @@ -50,6 +50,10 @@ struct ClusterCountCmdS { static void checkCanRunHere(OperationContext* opCtx) { // Can always run on a mongos. } + + static void checkCanExplainHere(OperationContext* opCtx) { + // Can always run on a mongos. + } }; ClusterCountCmdBase<ClusterCountCmdS> clusterCountCmdS; diff --git a/src/mongo/s/commands/cluster_find_cmd.h b/src/mongo/s/commands/cluster_find_cmd.h index 4349e3558a1..b533b9abe40 100644 --- a/src/mongo/s/commands/cluster_find_cmd.h +++ b/src/mongo/s/commands/cluster_find_cmd.h @@ -141,7 +141,7 @@ public: const auto explainCmd = ClusterExplain::wrapAsExplain(findCommand->toBSON(BSONObj()), verbosity); - Impl::checkCanRunHere(opCtx); + Impl::checkCanExplainHere(opCtx); long long millisElapsed; std::vector<AsyncRequestsSender::Response> shardResponses; diff --git a/src/mongo/s/commands/cluster_find_cmd_s.cpp b/src/mongo/s/commands/cluster_find_cmd_s.cpp index 793d14999be..a46cedaf47e 100644 --- a/src/mongo/s/commands/cluster_find_cmd_s.cpp +++ b/src/mongo/s/commands/cluster_find_cmd_s.cpp @@ -52,6 +52,10 @@ struct ClusterFindCmdS { static void checkCanRunHere(OperationContext* opCtx) { // Can always run on a mongos. } + + static void checkCanExplainHere(OperationContext* opCtx) { + // Can always run on a mongos. + } }; ClusterFindCmdBase<ClusterFindCmdS> clusterFindCmdS; diff --git a/src/mongo/s/commands/cluster_pipeline_cmd.h b/src/mongo/s/commands/cluster_pipeline_cmd.h index d2f6cff32eb..8ac60460ad8 100644 --- a/src/mongo/s/commands/cluster_pipeline_cmd.h +++ b/src/mongo/s/commands/cluster_pipeline_cmd.h @@ -155,7 +155,7 @@ public: void explain(OperationContext* opCtx, ExplainOptions::Verbosity verbosity, rpc::ReplyBuilderInterface* result) override { - Impl::checkCanRunHere(opCtx); + Impl::checkCanExplainHere(opCtx); auto bodyBuilder = result->getBodyBuilder(); _runAggCommand(opCtx, _dbName, _request.body, &bodyBuilder); } diff --git a/src/mongo/s/commands/cluster_pipeline_cmd_s.cpp b/src/mongo/s/commands/cluster_pipeline_cmd_s.cpp index 771f84d1119..8930e532fa6 100644 --- a/src/mongo/s/commands/cluster_pipeline_cmd_s.cpp +++ b/src/mongo/s/commands/cluster_pipeline_cmd_s.cpp @@ -53,6 +53,10 @@ struct ClusterPipelineCommandS { // Can always run on a mongos. } + static void checkCanExplainHere(OperationContext* opCtx) { + // Can always run on a mongos. + } + static AggregateCommandRequest parseAggregationRequest( OperationContext* opCtx, const OpMsgRequest& opMsgRequest, diff --git a/src/mongo/s/commands/cluster_write_cmd.cpp b/src/mongo/s/commands/cluster_write_cmd.cpp index 4bcf8cb07c4..45dcd81274a 100644 --- a/src/mongo/s/commands/cluster_write_cmd.cpp +++ b/src/mongo/s/commands/cluster_write_cmd.cpp @@ -651,7 +651,7 @@ void ClusterWriteCmd::InvocationBase::run(OperationContext* opCtx, void ClusterWriteCmd::InvocationBase::explain(OperationContext* opCtx, ExplainOptions::Verbosity verbosity, rpc::ReplyBuilderInterface* result) { - preRunImplHook(opCtx); + preExplainImplHook(opCtx); uassert(ErrorCodes::InvalidLength, "explained write batches must be of size 1", diff --git a/src/mongo/s/commands/cluster_write_cmd.h b/src/mongo/s/commands/cluster_write_cmd.h index c3632b5246d..2b0bb507423 100644 --- a/src/mongo/s/commands/cluster_write_cmd.h +++ b/src/mongo/s/commands/cluster_write_cmd.h @@ -102,6 +102,7 @@ public: private: virtual void preRunImplHook(OperationContext* opCtx) const = 0; + virtual void preExplainImplHook(OperationContext* opCtx) const = 0; virtual void doCheckAuthorizationHook(AuthorizationSession* authzSession) const = 0; bool runImpl(OperationContext* opCtx, @@ -162,6 +163,10 @@ private: Impl::checkCanRunHere(opCtx); } + void preExplainImplHook(OperationContext* opCtx) const final { + Impl::checkCanExplainHere(opCtx); + } + void doCheckAuthorizationHook(AuthorizationSession* authzSession) const final { Impl::doCheckAuthorization( authzSession, getBypass(), getBatchedRequest().getInsertRequest()); @@ -208,6 +213,10 @@ private: Impl::checkCanRunHere(opCtx); } + void preExplainImplHook(OperationContext* opCtx) const final { + Impl::checkCanExplainHere(opCtx); + } + void doCheckAuthorizationHook(AuthorizationSession* authzSession) const final { Impl::doCheckAuthorization( authzSession, getBypass(), getBatchedRequest().getUpdateRequest()); @@ -260,6 +269,10 @@ private: Impl::checkCanRunHere(opCtx); } + void preExplainImplHook(OperationContext* opCtx) const final { + Impl::checkCanExplainHere(opCtx); + } + void doCheckAuthorizationHook(AuthorizationSession* authzSession) const final { Impl::doCheckAuthorization( authzSession, getBypass(), getBatchedRequest().getDeleteRequest()); diff --git a/src/mongo/s/commands/cluster_write_cmd_s.cpp b/src/mongo/s/commands/cluster_write_cmd_s.cpp index f9b8c8020b3..c7c5781f8c0 100644 --- a/src/mongo/s/commands/cluster_write_cmd_s.cpp +++ b/src/mongo/s/commands/cluster_write_cmd_s.cpp @@ -48,6 +48,10 @@ struct ClusterInsertCmdS { static void checkCanRunHere(OperationContext* opCtx) { // Can always run on a mongos. } + + static void checkCanExplainHere(OperationContext* opCtx) { + // Can always run on a mongos. + } }; ClusterInsertCmdBase<ClusterInsertCmdS> clusterInsertCmdS; @@ -67,6 +71,10 @@ struct ClusterUpdateCmdS { static void checkCanRunHere(OperationContext* opCtx) { // Can always run on a mongos. } + + static void checkCanExplainHere(OperationContext* opCtx) { + // Can always run on a mongos. + } }; ClusterUpdateCmdBase<ClusterUpdateCmdS> clusterUpdateCmdS; @@ -86,6 +94,10 @@ struct ClusterDeleteCmdS { static void checkCanRunHere(OperationContext* opCtx) { // Can always run on a mongos. } + + static void checkCanExplainHere(OperationContext* opCtx) { + // Can always run on a mongos. + } }; ClusterDeleteCmdBase<ClusterDeleteCmdS> clusterDeleteCmdS; |