236 lines
8.9 KiB
JavaScript
236 lines
8.9 KiB
JavaScript
// Test copyDatabase command with various combinations of authed/unauthed and single node/replica
|
|
// set source and dest.
|
|
|
|
TestData.authMechanism = "SCRAM-SHA-1"; // SERVER-11428
|
|
DB.prototype._defaultAuthenticationMechanism = "SCRAM-SHA-1"; // SERVER-11428
|
|
|
|
var baseName = "jstests_clone_copyauth";
|
|
|
|
/*
|
|
* Helper to spawn a replica set, sharded cluster, or a single mongod and hide it all behind the
|
|
* same interface.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* clusterType - type of cluster to start. Options are "sharded", "repl", or "single".
|
|
* startWithAuth - whether to start the cluster with authentication.
|
|
*
|
|
* Member variables:
|
|
*
|
|
* conn - a connection to the node used to access this cluster, whether it's the mongod, a primary
|
|
* mongod in a replica set, or a mongos.
|
|
* connString - the full connection string used to connect to this cluster. For a replica set this
|
|
* is the full connection string including the replica set name.
|
|
*
|
|
* Member functions:
|
|
*
|
|
* stop() - stop and cleanup whatever nodes the helper spawned when it was created.
|
|
*/
|
|
function ClusterSpawnHelper(clusterType, startWithAuth) {
|
|
|
|
if (clusterType === "sharded") {
|
|
var shardingTestConfig = {
|
|
name : baseName + "_source",
|
|
mongos : 1,
|
|
shards : 1,
|
|
config : 1
|
|
}
|
|
if (startWithAuth) {
|
|
shardingTestConfig.auth = "";
|
|
shardingTestConfig.keyFile = "jstests/libs/key1";
|
|
}
|
|
var shardingTest = new ShardingTest(shardingTestConfig);
|
|
this.conn = shardingTest.s;
|
|
this.connString = this.conn.host;
|
|
}
|
|
else if (clusterType === "repl") {
|
|
var replSetTestConfig = { name: baseName + "_source", nodes: 3, nodeOptions: {} };
|
|
if (startWithAuth) {
|
|
replSetTestConfig.nodeOptions.auth = "";
|
|
replSetTestConfig.nodeOptions.keyFile = "jstests/libs/key1";
|
|
}
|
|
var replSetTest = new ReplSetTest(replSetTestConfig);
|
|
replSetTest.startSet();
|
|
replSetTest.initiate();
|
|
if (startWithAuth) {
|
|
authutil.asCluster(replSetTest.nodes,
|
|
replSetTestConfig.nodeOptions.keyFile,
|
|
function() { replSetTest.awaitReplication(); });
|
|
}
|
|
else {
|
|
replSetTest.awaitReplication();
|
|
}
|
|
this.conn = replSetTest.getMaster();
|
|
this.connString = replSetTest.getURL();
|
|
}
|
|
else {
|
|
var singleNodeConfig = {};
|
|
if (startWithAuth) {
|
|
singleNodeConfig.auth = "";
|
|
}
|
|
this.conn = MongoRunner.runMongod(singleNodeConfig);
|
|
this.connString = this.conn.host;
|
|
}
|
|
|
|
this.stop = function () {
|
|
if (clusterType === "sharded") {
|
|
shardingTest.stop();
|
|
}
|
|
else if (clusterType === "repl") {
|
|
replSetTest.stopSet();
|
|
}
|
|
else {
|
|
MongoRunner.stopMongod(this.conn.port);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Helper to test the running the "copydb" command between various kinds of clusters and various
|
|
* combinations of authentication on the source and target.
|
|
*
|
|
* @param {Object} configObj
|
|
*
|
|
* {
|
|
* sourceClusterType {string}: Type of cluster to use as the source of the copy. Options are
|
|
* "single", "repl", "sharded".
|
|
* isSourceUsingAuth {bool}: Whether to use auth in the source cluster for the copy.
|
|
* targetClusterType {string}: Type of cluster to use as the target of the copy. Options are
|
|
* "single", "repl", "sharded".
|
|
* isTargetUsingAuth {bool}: Whether to use auth in the target cluster for the copy.
|
|
* }
|
|
*/
|
|
function copydbBetweenClustersTest(configObj) {
|
|
|
|
|
|
|
|
// First sanity check the arguments in our configObj
|
|
var requiredKeys = [
|
|
'sourceClusterType',
|
|
'isSourceUsingAuth',
|
|
'targetClusterType',
|
|
'isTargetUsingAuth'
|
|
]
|
|
|
|
var i;
|
|
for (i = 0; i < requiredKeys.length; i++) {
|
|
assert(configObj.hasOwnProperty(requiredKeys[i]),
|
|
"Missing required key: " + requiredKeys[i] + " in config object");
|
|
}
|
|
|
|
|
|
|
|
// 1. Get a connection to the source database, insert data and setup auth if applicable
|
|
source = new ClusterSpawnHelper(configObj.sourceClusterType, configObj.isSourceUsingAuth);
|
|
|
|
if (configObj.isSourceUsingAuth) {
|
|
// Create a super user so we can create a regular user and not be locked out afterwards
|
|
source.conn.getDB("admin").createUser({ user: "sourceSuperUser", pwd: "sourceSuperUser",
|
|
roles: [ "root" ] });
|
|
source.conn.getDB("admin").auth("sourceSuperUser", "sourceSuperUser");
|
|
|
|
source.conn.getDB(baseName)[baseName].save({i:1});
|
|
assert.eq(1, source.conn.getDB(baseName)[baseName].count());
|
|
assert.eq(1, source.conn.getDB(baseName)[baseName].findOne().i);
|
|
|
|
// Insert a document and create a regular user that we will use for the target
|
|
// authenticating with the source
|
|
source.conn.getDB(baseName).createUser({ user: "foo", pwd: "bar",
|
|
roles: [ "dbOwner" ] });
|
|
|
|
source.conn.getDB("admin").logout();
|
|
assert.throws(function() { source.conn.getDB(baseName)[baseName].findOne(); });
|
|
} else {
|
|
source.conn.getDB(baseName)[baseName].save({i:1});
|
|
assert.eq(1, source.conn.getDB(baseName)[baseName].count());
|
|
assert.eq(1, source.conn.getDB(baseName)[baseName].findOne().i);
|
|
}
|
|
|
|
|
|
|
|
// 2. Get a connection to the target database, and set up auth if necessary
|
|
target = new ClusterSpawnHelper(configObj.targetClusterType, configObj.isTargetUsingAuth);
|
|
|
|
if (configObj.isTargetUsingAuth) {
|
|
target.conn.getDB("admin").createUser({ user: "targetSuperUser", pwd: "targetSuperUser",
|
|
roles: [ "root" ] });
|
|
assert.throws(function() { target.conn.getDB(baseName)[baseName].findOne(); });
|
|
target.conn.getDB("admin").auth("targetSuperUser", "targetSuperUser");
|
|
}
|
|
|
|
|
|
|
|
// 3. Run the copydb command
|
|
target.conn.getDB(baseName).dropDatabase();
|
|
assert.eq(0, target.conn.getDB(baseName)[baseName].count());
|
|
if (configObj.isSourceUsingAuth) {
|
|
// We only need to pass username and password if the target has to send authentication
|
|
// information to the source cluster
|
|
assert.commandWorked(target.conn.getDB(baseName).copyDatabase(baseName, baseName,
|
|
source.connString,
|
|
"foo", "bar"));
|
|
}
|
|
else {
|
|
// We are copying from a cluster with no auth
|
|
assert.commandWorked(target.conn.getDB(baseName).copyDatabase(baseName, baseName,
|
|
source.connString));
|
|
}
|
|
assert.eq(1, target.conn.getDB(baseName)[baseName].count());
|
|
assert.eq(1, target.conn.getDB(baseName)[baseName].findOne().i);
|
|
|
|
|
|
|
|
// 4. Do any necessary cleanup
|
|
source.stop();
|
|
target.stop();
|
|
}
|
|
|
|
(function() {
|
|
"use strict"
|
|
|
|
var sourceClusterTypeValues = [ "single", "repl", "sharded" ]
|
|
var isSourceUsingAuthValues = [ true, false ]
|
|
var targetClusterTypeValues = [ "single", "repl", "sharded" ]
|
|
var isTargetUsingAuthValues = [ true, false ]
|
|
for (var i = 0; i < sourceClusterTypeValues.length; i++) {
|
|
for (var j = 0; j < isSourceUsingAuthValues.length; j++) {
|
|
for (var k = 0; k < targetClusterTypeValues.length; k++) {
|
|
for (var l = 0; l < isTargetUsingAuthValues.length; l++) {
|
|
if (sourceClusterTypeValues[i] === "sharded" &&
|
|
targetClusterTypeValues[k] === "sharded") {
|
|
// SERVER-13112
|
|
continue;
|
|
}
|
|
if (sourceClusterTypeValues[i] === "repl" &&
|
|
targetClusterTypeValues[k] === "repl") {
|
|
// SERVER-13077
|
|
continue;
|
|
}
|
|
if (isSourceUsingAuthValues[j] === true &&
|
|
targetClusterTypeValues[k] === "sharded") {
|
|
// SERVER-6427
|
|
continue;
|
|
}
|
|
if (sourceClusterTypeValues[i] === "repl" &&
|
|
isSourceUsingAuthValues[j] === false &&
|
|
targetClusterTypeValues[k] === "sharded" &&
|
|
isTargetUsingAuthValues[l] == true) {
|
|
// SERVER-18103
|
|
continue;
|
|
}
|
|
var testCase = {
|
|
'sourceClusterType' : sourceClusterTypeValues[i],
|
|
'isSourceUsingAuth' : isSourceUsingAuthValues[j],
|
|
'targetClusterType' : targetClusterTypeValues[k],
|
|
'isTargetUsingAuth' : isTargetUsingAuthValues[l]
|
|
}
|
|
print("Running copydb with auth test:");
|
|
printjson(testCase);
|
|
copydbBetweenClustersTest(testCase);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}());
|
|
print(baseName + " success!");
|