summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/noPassthrough/cluster_explain_commands_not_supported.js87
-rw-r--r--jstests/noPassthrough/cluster_explain_commands_require_cluster_node.js37
-rw-r--r--src/mongo/db/s/cluster_count_cmd_d.cpp5
-rw-r--r--src/mongo/db/s/cluster_find_cmd_d.cpp5
-rw-r--r--src/mongo/db/s/cluster_pipeline_cmd_d.cpp5
-rw-r--r--src/mongo/db/s/cluster_write_cmd_d.cpp14
-rw-r--r--src/mongo/s/commands/cluster_count_cmd.h2
-rw-r--r--src/mongo/s/commands/cluster_count_cmd_s.cpp4
-rw-r--r--src/mongo/s/commands/cluster_find_cmd.h2
-rw-r--r--src/mongo/s/commands/cluster_find_cmd_s.cpp4
-rw-r--r--src/mongo/s/commands/cluster_pipeline_cmd.h2
-rw-r--r--src/mongo/s/commands/cluster_pipeline_cmd_s.cpp4
-rw-r--r--src/mongo/s/commands/cluster_write_cmd.cpp2
-rw-r--r--src/mongo/s/commands/cluster_write_cmd.h13
-rw-r--r--src/mongo/s/commands/cluster_write_cmd_s.cpp12
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;