mirror of https://github.com/mongodb/mongo
171 lines
6.4 KiB
JavaScript
171 lines
6.4 KiB
JavaScript
/**
|
|
* Tests that direct shard connections are correctly allowed and disallowed using authentication.
|
|
*
|
|
* @tags: [requires_fcv_73]
|
|
*/
|
|
import {configureFailPoint} from "jstests/libs/fail_point_util.js";
|
|
import {ShardingTest} from "jstests/libs/shardingtest.js";
|
|
|
|
const st = new ShardingTest({
|
|
name: jsTestName(),
|
|
keyFile: "jstests/libs/key1",
|
|
shards: 2,
|
|
// Disallow chaining so that when testing replSetAbortPrimaryCatchUp we have the guarantee that
|
|
// the secondary is syncing from the primary.
|
|
rs0: {nodes: 3, settings: {chainingAllowed: false}},
|
|
// By default, our test infrastructure sets the election timeout to a very high value (24
|
|
// hours). For this test, we need a shorter election timeout because it relies on nodes running
|
|
// an election when they do not detect an active primary. Therefore, we are setting the
|
|
// electionTimeoutMillis to its default value.
|
|
initiateWithDefaultElectionTimeout: true,
|
|
});
|
|
|
|
const shardConn = st.rs0.getPrimary();
|
|
const shardAdminDB = shardConn.getDB("admin");
|
|
|
|
jsTest.log("Setup users for test");
|
|
shardAdminDB.createUser({user: "admin", pwd: "x", roles: ["root"]});
|
|
assert(shardAdminDB.auth("admin", "x"), "Authentication failed");
|
|
assert.commandWorked(
|
|
shardAdminDB.runCommand({
|
|
setParameter: 1,
|
|
logComponentVerbosity: {sharding: {verbosity: 2}, assert: {verbosity: 1}},
|
|
}),
|
|
);
|
|
// The replSetStateChange action type is needed for this test
|
|
shardAdminDB.createUser({user: "user", pwd: "y", roles: ["clusterManager"]});
|
|
shardAdminDB.logout();
|
|
|
|
function awaitReplication(rst) {
|
|
let nodes = rst.nodes;
|
|
authutil.asCluster(nodes, "jstests/libs/key1", function () {
|
|
rst.awaitReplication();
|
|
});
|
|
}
|
|
|
|
function setupConn(conn, user, pwd) {
|
|
let newConn = new Mongo(conn.host);
|
|
assert(newConn.getDB("admin").auth(user, pwd), "Authentication failed");
|
|
return newConn;
|
|
}
|
|
|
|
function runAsAdminUser(conn, cmd, database) {
|
|
let newConn = setupConn(conn, "admin", "x");
|
|
let res = assert.commandWorked(newConn.getDB(database).runCommand(cmd));
|
|
newConn.close();
|
|
return res;
|
|
}
|
|
|
|
jsTest.log("Await replication to ensure the user is created on all nodes");
|
|
awaitReplication(st.rs0);
|
|
|
|
jsTest.log("Testing replSetStepDown and replSetStepUp");
|
|
{
|
|
let secondaryConn = setupConn(st.rs0.getSecondary(), "user", "y");
|
|
assert.commandWorked(secondaryConn.adminCommand({replSetStepUp: 1}));
|
|
authutil.asCluster(st.rs0.nodes, "jstests/libs/key1", function () {
|
|
st.rs0.awaitNodesAgreeOnPrimary();
|
|
st.rs0.awaitSecondaryNodes();
|
|
});
|
|
assert.soonNoExcept(() => {
|
|
// {replSetStepDown: 0} defaults to 60 seconds rather than 0, so specify 1 here and unfreeze
|
|
// the node later in the test if it will be stepped up to primary.
|
|
return secondaryConn.adminCommand({replSetStepDown: 1, force: true}).ok;
|
|
}, `failed attempt to step down node ${secondaryConn.host}`);
|
|
authutil.asCluster(st.rs0.nodes, "jstests/libs/key1", function () {
|
|
st.rs0.awaitNodesAgreeOnPrimary();
|
|
st.rs0.awaitSecondaryNodes();
|
|
});
|
|
secondaryConn.close();
|
|
}
|
|
|
|
jsTest.log("Testing replSetFreeze");
|
|
{
|
|
let secondaryConn = setupConn(st.rs0.getSecondary(), "user", "y");
|
|
assert.commandWorked(secondaryConn.adminCommand({replSetFreeze: 1}));
|
|
assert.commandWorked(secondaryConn.adminCommand({replSetFreeze: 0}));
|
|
secondaryConn.close();
|
|
}
|
|
|
|
jsTest.log("Testing replSetMaintenance");
|
|
{
|
|
let secondaryConn = setupConn(st.rs0.getSecondary(), "user", "y");
|
|
assert.commandWorked(secondaryConn.adminCommand({replSetMaintenance: 1}));
|
|
assert.commandWorked(secondaryConn.adminCommand({replSetMaintenance: 0}));
|
|
secondaryConn.close();
|
|
}
|
|
|
|
jsTest.log("Testing replSetSyncFrom");
|
|
{
|
|
let primary = st.rs0.getPrimary();
|
|
let secondary1 = st.rs0.getSecondaries()[0];
|
|
let secondary2Conn = setupConn(st.rs0.getSecondaries()[1], "user", "y");
|
|
|
|
assert.commandWorked(secondary2Conn.adminCommand({replSetSyncFrom: secondary1.name}));
|
|
assert.commandWorked(secondary2Conn.adminCommand({replSetSyncFrom: primary.name}));
|
|
secondary2Conn.close();
|
|
}
|
|
|
|
jsTest.log("Testing replSetAbortPrimaryCatchUp");
|
|
{
|
|
let primary = st.rs0.getPrimary();
|
|
let secondary1 = st.rs0.getSecondaries()[0];
|
|
let secondary2 = st.rs0.getSecondaries()[1];
|
|
|
|
let primaryConn = setupConn(primary, "user", "y");
|
|
let secondary1Conn = setupConn(secondary1, "user", "y");
|
|
let secondary2Conn = setupConn(secondary2, "user", "y");
|
|
// Ensure the secondary we plan to step up isn't frozen from a prior step down
|
|
assert.commandWorked(secondary1Conn.adminCommand({replSetFreeze: 0}));
|
|
|
|
// Reconfig to make the catchup timeout infinite.
|
|
let newConfig = assert.commandWorked(primaryConn.adminCommand({replSetGetConfig: 1})).config;
|
|
newConfig.version++;
|
|
newConfig.settings.catchUpTimeoutMillis = -1;
|
|
assert.commandWorked(primaryConn.adminCommand({replSetReconfig: newConfig}));
|
|
// Put new secondary into primary catch up
|
|
const stopReplProducerFailPoint2 = configureFailPoint(secondary2Conn, "stopReplProducer");
|
|
stopReplProducerFailPoint2.wait();
|
|
runAsAdminUser(primary, {insert: "catch_up", documents: [{_id: 0}]}, "test");
|
|
assert.soon(() => {
|
|
let count = runAsAdminUser(
|
|
secondary1,
|
|
{
|
|
count: "catch_up",
|
|
readConcern: {level: "local"},
|
|
$readPreference: {mode: "secondary"},
|
|
},
|
|
"test",
|
|
).n;
|
|
return count == 1;
|
|
});
|
|
const stopReplProducerFailPoint1 = configureFailPoint(secondary1Conn, "stopReplProducer");
|
|
stopReplProducerFailPoint1.wait();
|
|
runAsAdminUser(primary, {insert: "catch_up", documents: [{_id: 1}]}, "test");
|
|
// Step up the first secondary, it will enter catch up indefinitely
|
|
assert.commandWorked(secondary1Conn.adminCommand({replSetStepUp: 1}));
|
|
|
|
// Now we can abort the catch up
|
|
assert.commandWorked(secondary1Conn.adminCommand({replSetAbortPrimaryCatchUp: 1}));
|
|
|
|
stopReplProducerFailPoint1.off();
|
|
stopReplProducerFailPoint2.off();
|
|
|
|
primaryConn.close();
|
|
secondary1Conn.close();
|
|
secondary2Conn.close();
|
|
|
|
authutil.asCluster(st.rs0.nodes, "jstests/libs/key1", function () {
|
|
st.rs0.awaitNodesAgreeOnPrimary();
|
|
st.rs0.awaitSecondaryNodes();
|
|
});
|
|
}
|
|
|
|
let primaryConn = setupConn(st.rs0.getPrimary(), "admin", "x");
|
|
let primaryAdminDB = primaryConn.getDB("admin");
|
|
primaryAdminDB.dropUser("user");
|
|
primaryAdminDB.dropUser("directOperationsUser");
|
|
primaryConn.close();
|
|
|
|
st.stop();
|