diff options
author | Marcos Jose Grillo Ramirez <marcos.grillo@mongodb.com> | 2022-03-18 10:51:00 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-03-18 11:43:05 +0000 |
commit | b1dc7f546a006efa5edf063286e4368ca603fe48 (patch) | |
tree | 43624a20b5d81f23a1936bec88a91ce388992dd8 | |
parent | ebb1f3900176b9df1f3c20646f349c9785914c43 (diff) | |
download | mongo-b1dc7f546a006efa5edf063286e4368ca603fe48.tar.gz |
SERVER-62265 Add setClusterParameter command to mongos
19 files changed, 225 insertions, 14 deletions
diff --git a/jstests/auth/lib/commands_lib.js b/jstests/auth/lib/commands_lib.js index 6a3be948448..95b93b31fdb 100644 --- a/jstests/auth/lib/commands_lib.js +++ b/jstests/auth/lib/commands_lib.js @@ -5589,6 +5589,18 @@ var authCommandsLib = { ] }, { + testname: "setClusterParameter", + command: {setClusterParameter: {param: true}}, + skipTest: (conn) => !TestData.setParameters.featureFlagClusterWideConfig, + testcases: [ + { + runOnDb: adminDbName, + roles: {clusterManager: 1, clusterAdmin: 1, root:1, __system:1}, + privileges: [{resource: {cluster: true}, actions: ["setClusterParameter"]}] + } + ] + }, + { testname: "setDefaultRWConcern", command: { setDefaultRWConcern: 1, diff --git a/jstests/core/views/views_all_commands.js b/jstests/core/views/views_all_commands.js index aaeb10a577e..8b6f51f6a46 100644 --- a/jstests/core/views/views_all_commands.js +++ b/jstests/core/views/views_all_commands.js @@ -603,6 +603,7 @@ let viewsCommandTests = { setFreeMonitoring: {skip: isUnrelated}, setParameter: {skip: isUnrelated}, setShardVersion: {skip: isUnrelated}, + setClusterParameter: {skip: isUnrelated}, setUserWriteBlockMode: {skip: isUnrelated}, shardCollection: { command: {shardCollection: "test.view", key: {_id: 1}}, diff --git a/jstests/replsets/db_reads_while_recovering_all_commands.js b/jstests/replsets/db_reads_while_recovering_all_commands.js index 59ec99d3347..09e4ca52be2 100644 --- a/jstests/replsets/db_reads_while_recovering_all_commands.js +++ b/jstests/replsets/db_reads_while_recovering_all_commands.js @@ -329,6 +329,7 @@ const allCommands = { setFreeMonitoring: {skip: isPrimaryOnly}, setParameter: {skip: isNotAUserDataRead}, setShardVersion: {skip: isNotAUserDataRead}, + setClusterParameter: {skip: isNotAUserDataRead}, setUserWriteBlockMode: {skip: isPrimaryOnly}, shardingState: {skip: isNotAUserDataRead}, shutdown: {skip: isNotAUserDataRead}, diff --git a/jstests/sharding/database_versioning_all_commands.js b/jstests/sharding/database_versioning_all_commands.js index f201c0ebdb0..2b8730cc919 100644 --- a/jstests/sharding/database_versioning_all_commands.js +++ b/jstests/sharding/database_versioning_all_commands.js @@ -644,6 +644,7 @@ let testCases = { setFreeMonitoring: {skip: "explicitly fails for mongos, primary mongod only", conditional: true}, setParameter: {skip: "executes locally on mongos (not sent to any remote node)"}, + setClusterParameter: {skip: "always targets the config server"}, setUserWriteBlockMode: {skip: "executes locally on mongos (not sent to any remote node)"}, shardCollection: {skip: "does not forward command to primary shard"}, shutdown: {skip: "does not forward command to primary shard"}, diff --git a/jstests/sharding/libs/last_lts_mongod_commands.js b/jstests/sharding/libs/last_lts_mongod_commands.js index 03b25c1d0a8..7db68cdfdea 100644 --- a/jstests/sharding/libs/last_lts_mongod_commands.js +++ b/jstests/sharding/libs/last_lts_mongod_commands.js @@ -16,5 +16,6 @@ const commandsAddedToMongodSinceLastLTS = [ "clusterCommitTransaction", "clusterFind", "rotateCertificates", + "setClusterParameter", "setUserWriteBlockMode", ]; diff --git a/jstests/sharding/libs/last_lts_mongos_commands.js b/jstests/sharding/libs/last_lts_mongos_commands.js index 611f2197a6f..61ca80b0633 100644 --- a/jstests/sharding/libs/last_lts_mongos_commands.js +++ b/jstests/sharding/libs/last_lts_mongos_commands.js @@ -20,6 +20,7 @@ const commandsAddedToMongosSinceLastLTS = [ "reshardCollection", "rotateCertificates", "setAllowMigrations", + "setClusterParameter", "setUserWriteBlockMode", "testDeprecation", "testDeprecationInVersion2", diff --git a/jstests/sharding/read_write_concern_defaults_application.js b/jstests/sharding/read_write_concern_defaults_application.js index 201bfc77dab..b25200f38c8 100644 --- a/jstests/sharding/read_write_concern_defaults_application.js +++ b/jstests/sharding/read_write_concern_defaults_application.js @@ -686,6 +686,7 @@ let testCases = { setIndexCommitQuorum: {skip: "does not accept read or write concern"}, setParameter: {skip: "does not accept read or write concern"}, setShardVersion: {skip: "internal command"}, + setClusterParameter: {skip: "does not accept read or write concern"}, setUserWriteBlockMode: {skip: "does not accept read or write concern"}, shardCollection: {skip: "does not accept read or write concern"}, shardingState: {skip: "does not accept read or write concern"}, diff --git a/jstests/sharding/safe_secondary_reads_drop_recreate.js b/jstests/sharding/safe_secondary_reads_drop_recreate.js index 6087ce590de..fac7acafd51 100644 --- a/jstests/sharding/safe_secondary_reads_drop_recreate.js +++ b/jstests/sharding/safe_secondary_reads_drop_recreate.js @@ -323,6 +323,7 @@ let testCases = { setFreeMonitoring: {skip: "primary only"}, setParameter: {skip: "does not return user data"}, setShardVersion: {skip: "does not return user data"}, + setClusterParameter: {skip: "does not return user data"}, setUserWriteBlockMode: {skip: "primary only"}, shardCollection: {skip: "primary only"}, shardingState: {skip: "does not return user data"}, diff --git a/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js b/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js index 2c4ab0ae4b3..ba438ed7a67 100644 --- a/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js +++ b/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js @@ -394,6 +394,7 @@ let testCases = { setFreeMonitoring: {skip: "primary only"}, setParameter: {skip: "does not return user data"}, setShardVersion: {skip: "does not return user data"}, + setClusterParameter: {skip: "does not return user data"}, setUserWriteBlockMode: {skip: "primary only"}, shardCollection: {skip: "primary only"}, shardingState: {skip: "does not return user data"}, diff --git a/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js b/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js index c6e0ce59c88..5ac2f0166bf 100644 --- a/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js +++ b/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js @@ -330,6 +330,7 @@ let testCases = { setFreeMonitoring: {skip: "primary only"}, setParameter: {skip: "does not return user data"}, setShardVersion: {skip: "does not return user data"}, + setClusterParameter: {skip: "does not return user data"}, setUserWriteBlockMode: {skip: "primary only"}, shardCollection: {skip: "primary only"}, shardingState: {skip: "does not return user data"}, diff --git a/jstests/sharding/configsvr_set_cluster_parameter.js b/jstests/sharding/set_cluster_parameter.js index fc54e1de728..ad550c6b685 100644 --- a/jstests/sharding/configsvr_set_cluster_parameter.js +++ b/jstests/sharding/set_cluster_parameter.js @@ -1,5 +1,5 @@ /** - * Checks that _configsvrSetClusterParameter command only run once + * Checks that setClusterParameter command only run once * * @tags: [ * # Requires all nodes to be running the latest binary. @@ -18,10 +18,10 @@ const st = new ShardingTest({shards: 1}); let fp = configureFailPoint(st.configRS.getPrimary(), 'hangBeforeRunningConfigsvrCoordinatorInstance'); -let setClusterParameterSuccessThread = new Thread((mongodConnString) => { - let mongod = new Mongo(mongodConnString); - assert.commandWorked(mongod.adminCommand({_configsvrSetClusterParameter: {param: true}})); -}, st.configRS.getPrimary().host); +let setClusterParameterSuccessThread = new Thread((mongosConnString) => { + let mongos = new Mongo(mongosConnString); + assert.commandWorked(mongos.adminCommand({setClusterParameter: {param: true}})); +}, st.s.host); setClusterParameterSuccessThread.start(); fp.wait(); @@ -29,10 +29,10 @@ fp.wait(); jsTestLog( 'Check that 2 requests for the same cluster parameter and same value generates only one coordinator.'); -let setClusterParameterJoinSuccessThread = new Thread((mongodConnString) => { - let mongod = new Mongo(mongodConnString); - assert.commandWorked(mongod.adminCommand({_configsvrSetClusterParameter: {param: true}})); -}, st.configRS.getPrimary().host); +let setClusterParameterJoinSuccessThread = new Thread((mongosConnString) => { + let mongos = new Mongo(mongosConnString); + assert.commandWorked(mongos.adminCommand({setClusterParameter: {param: true}})); +}, st.s.host); setClusterParameterJoinSuccessThread.start(); @@ -49,9 +49,8 @@ assert.eq(true, currOp[0].command.param); jsTestLog('Check that a second request will fail with ConflictingOperationInProgress.'); -assert.commandFailedWithCode( - st.configRS.getPrimary().adminCommand({_configsvrSetClusterParameter: {otherParam: true}}), - ErrorCodes.ConflictingOperationInProgress); +assert.commandFailedWithCode(st.s.adminCommand({setClusterParameter: {otherParam: true}}), + ErrorCodes.ConflictingOperationInProgress); fp.off(); setClusterParameterSuccessThread.join(); diff --git a/src/mongo/db/auth/action_type.idl b/src/mongo/db/auth/action_type.idl index 42d850d880b..dc11b26fb4a 100644 --- a/src/mongo/db/auth/action_type.idl +++ b/src/mongo/db/auth/action_type.idl @@ -161,6 +161,7 @@ enums: serverStatus : "serverStatus" setAuthenticationRestriction : "setAuthenticationRestriction" setChangeStreamOptions: "setChangeStreamOptions" + setClusterParameter: "setClusterParameter" setDefaultRWConcern : "setDefaultRWConcern" setFeatureCompatibilityVersion : "setFeatureCompatibilityVersion" setFreeMonitoring : "setFreeMonitoring" diff --git a/src/mongo/db/auth/builtin_roles.cpp b/src/mongo/db/auth/builtin_roles.cpp index d4dd9ce743b..cbad7142669 100644 --- a/src/mongo/db/auth/builtin_roles.cpp +++ b/src/mongo/db/auth/builtin_roles.cpp @@ -254,7 +254,8 @@ MONGO_INITIALIZER(AuthorizationBuiltinRoles)(InitializerContext* context) { << ActionType::setFeatureCompatibilityVersion << ActionType::setFreeMonitoring << ActionType::setChangeStreamOptions - << ActionType::getChangeStreamOptions; + << ActionType::getChangeStreamOptions + << ActionType::setClusterParameter; clusterManagerRoleDatabaseActions << ActionType::clearJumboFlag diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript index aca30381f2b..3c6fee64ed5 100644 --- a/src/mongo/db/commands/SConscript +++ b/src/mongo/db/commands/SConscript @@ -552,6 +552,7 @@ env.Library( "resize_oplog.cpp", "resize_oplog.idl", 'rwc_defaults_commands.cpp', + 'set_cluster_parameter_command.cpp', "set_feature_compatibility_version_command.cpp", "set_index_commit_quorum_command.cpp", "shutdown_d.cpp", diff --git a/src/mongo/db/commands/set_cluster_parameter_command.cpp b/src/mongo/db/commands/set_cluster_parameter_command.cpp new file mode 100644 index 00000000000..0abcb976955 --- /dev/null +++ b/src/mongo/db/commands/set_cluster_parameter_command.cpp @@ -0,0 +1,84 @@ +/** + * Copyright (C) 2022-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * 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 + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * 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 Server Side 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. + */ + +#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kCommand + +#include "mongo/platform/basic.h" + +#include "mongo/db/auth/authorization_session.h" +#include "mongo/db/commands.h" +#include "mongo/db/commands/set_cluster_parameter_gen.h" +#include "mongo/logv2/log.h" + +namespace mongo { + +namespace { + +class SetClusterParameterCommand final : public TypedCommand<SetClusterParameterCommand> { +public: + using Request = SetClusterParameter; + + AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { + return AllowedOnSecondary::kNever; + } + + bool adminOnly() const override { + return true; + } + + std::string help() const override { + return "Set cluster parameter on replica set or node"; + } + + class Invocation final : public InvocationBase { + public: + using InvocationBase::InvocationBase; + + void typedRun(OperationContext*) { + LOGV2(6226501, "Received setClusterParameter on node"); + } + + private: + bool supportsWriteConcern() const override { + return false; + } + NamespaceString ns() const override { + return NamespaceString(); + } + void doCheckAuthorization(OperationContext* opCtx) const override { + uassert(ErrorCodes::Unauthorized, + "Unauthorized", + AuthorizationSession::get(opCtx->getClient()) + ->isAuthorizedForPrivilege(Privilege{ResourcePattern::forClusterResource(), + ActionType::setClusterParameter})); + } + }; +} setClusterParameterCommand; +} // namespace +} // namespace mongo diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript index 497f62be4d3..538b1e481e0 100644 --- a/src/mongo/s/SConscript +++ b/src/mongo/s/SConscript @@ -234,6 +234,7 @@ env.Library( LIBDEPS=[ '$BUILD_DIR/mongo/client/connection_string', '$BUILD_DIR/mongo/db/coll_mod_command_idl', + '$BUILD_DIR/mongo/db/commands/set_cluster_parameter_idl', '$BUILD_DIR/mongo/db/commands/set_user_write_block_mode_idl', '$BUILD_DIR/mongo/db/common', '$BUILD_DIR/mongo/db/namespace_string', diff --git a/src/mongo/s/commands/SConscript b/src/mongo/s/commands/SConscript index 43f5aa29602..30e22cd955b 100644 --- a/src/mongo/s/commands/SConscript +++ b/src/mongo/s/commands/SConscript @@ -78,6 +78,7 @@ env.Library( 'cluster_reshard_collection_cmd.cpp', 'cluster_rwc_defaults_commands.cpp', 'cluster_set_allow_migrations_cmd.cpp', + 'cluster_set_cluster_parameter_cmd.cpp', 'cluster_set_feature_compatibility_version_cmd.cpp', 'cluster_set_free_monitoring_cmd.cpp' if get_option("enable-free-mon") == 'on' else [], 'cluster_set_index_commit_quorum_cmd.cpp', @@ -111,6 +112,7 @@ env.Library( '$BUILD_DIR/mongo/db/commands/rwc_defaults_commands', '$BUILD_DIR/mongo/db/commands/server_status', '$BUILD_DIR/mongo/db/commands/servers', + '$BUILD_DIR/mongo/db/commands/set_cluster_parameter_idl', '$BUILD_DIR/mongo/db/commands/set_feature_compatibility_version_idl', '$BUILD_DIR/mongo/db/commands/set_index_commit_quorum_idl', '$BUILD_DIR/mongo/db/commands/set_user_write_block_mode_idl', diff --git a/src/mongo/s/commands/cluster_set_cluster_parameter_cmd.cpp b/src/mongo/s/commands/cluster_set_cluster_parameter_cmd.cpp new file mode 100644 index 00000000000..6b5d4ce6e9e --- /dev/null +++ b/src/mongo/s/commands/cluster_set_cluster_parameter_cmd.cpp @@ -0,0 +1,101 @@ +/** + * Copyright (C) 2022-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * 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 + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * 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 Server Side 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. + */ + +#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kSharding + +#include "mongo/platform/basic.h" + +#include "mongo/db/auth/authorization_session.h" +#include "mongo/db/commands.h" +#include "mongo/db/commands/set_cluster_parameter_gen.h" +#include "mongo/s/cluster_commands_helpers.h" +#include "mongo/s/grid.h" +#include "mongo/s/request_types/sharded_ddl_commands_gen.h" + +namespace mongo { +namespace { + +class SetClusterParameterCmd final : public TypedCommand<SetClusterParameterCmd> { +public: + using Request = SetClusterParameter; + + AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { + return AllowedOnSecondary::kNever; + } + + bool adminOnly() const override { + return true; + } + + std::string help() const override { + return "Set a cluster wide parameter on every node"; + } + + class Invocation final : public InvocationBase { + public: + using InvocationBase::InvocationBase; + + void typedRun(OperationContext* opCtx) { + ConfigsvrSetClusterParameter configsvrSetClusterParameter( + request().getCommandParameter()); + configsvrSetClusterParameter.setDbName(ns().db()); + + const auto configShard = Grid::get(opCtx)->shardRegistry()->getConfigShard(); + + const auto cmdResponse = uassertStatusOK(configShard->runCommandWithFixedRetryAttempts( + opCtx, + ReadPreferenceSetting(ReadPreference::PrimaryOnly), + NamespaceString::kAdminDb.toString(), + configsvrSetClusterParameter.toBSON({}), + Shard::RetryPolicy::kIdempotent)); + + uassertStatusOK(Shard::CommandResponse::getEffectiveStatus(std::move(cmdResponse))); + } + + private: + bool supportsWriteConcern() const override { + return false; + } + + NamespaceString ns() const override { + return NamespaceString(); + } + + void doCheckAuthorization(OperationContext* opCtx) const override { + uassert(ErrorCodes::Unauthorized, + "Unauthorized", + AuthorizationSession::get(opCtx->getClient()) + ->isAuthorizedForPrivilege(Privilege{ResourcePattern::forClusterResource(), + ActionType::setClusterParameter})); + } + }; +} setClusterParameterCmd; + +} // namespace +} // namespace mongo diff --git a/src/mongo/s/request_types/sharded_ddl_commands.idl b/src/mongo/s/request_types/sharded_ddl_commands.idl index bd20052c334..7012ecda814 100644 --- a/src/mongo/s/request_types/sharded_ddl_commands.idl +++ b/src/mongo/s/request_types/sharded_ddl_commands.idl @@ -446,6 +446,6 @@ commands: cluster parameter." # TODO SERVER-63870: use replica set command parameters. namespace: type - type: object + type: object_owned api_version: "" strict: false |