diff --git a/fdbcli/TenantCommands.actor.cpp b/fdbcli/TenantCommands.actor.cpp index cb93b6c210..c341b0a248 100644 --- a/fdbcli/TenantCommands.actor.cpp +++ b/fdbcli/TenantCommands.actor.cpp @@ -35,10 +35,21 @@ namespace fdb_cli { -const KeyRangeRef tenantMapSpecialKeyRange(LiteralStringRef("\xff\xff/management/tenant/map/"), - LiteralStringRef("\xff\xff/management/tenant/map0")); -const KeyRangeRef tenantConfigSpecialKeyRange(LiteralStringRef("\xff\xff/management/tenant/configure/"), - LiteralStringRef("\xff\xff/management/tenant/configure0")); +const KeyRangeRef tenantMapSpecialKeyRange720("\xff\xff/management/tenant/map/"_sr, + "\xff\xff/management/tenant/map0"_sr); +const KeyRangeRef tenantConfigSpecialKeyRange("\xff\xff/management/tenant/configure/"_sr, + "\xff\xff/management/tenant/configure0"_sr); + +const KeyRangeRef tenantMapSpecialKeyRange710("\xff\xff/management/tenant_map/"_sr, + "\xff\xff/management/tenant_map0"_sr); + +KeyRangeRef const& tenantMapSpecialKeyRange(int apiVersion) { + if (apiVersion >= 720) { + return tenantMapSpecialKeyRange720; + } else { + return tenantMapSpecialKeyRange710; + } +} Optional, Optional>> parseTenantConfiguration(std::vector const& tokens, int startIndex, bool allowUnset) { @@ -94,13 +105,13 @@ void applyConfiguration(Reference tr, } // createtenant command -ACTOR Future createTenantCommandActor(Reference db, std::vector tokens) { +ACTOR Future createTenantCommandActor(Reference db, std::vector tokens, int apiVersion) { if (tokens.size() < 2 || tokens.size() > 3) { printUsage(tokens[0]); return false; } - state Key tenantNameKey = tenantMapSpecialKeyRange.begin.withSuffix(tokens[1]); + state Key tenantNameKey = tenantMapSpecialKeyRange(apiVersion).begin.withSuffix(tokens[1]); state Reference tr = db->createTransaction(); state bool doneExistenceCheck = false; @@ -111,6 +122,11 @@ ACTOR Future createTenantCommandActor(Reference db, std::vector return false; } + if (apiVersion < 720 && !configuration.get().empty()) { + fmt::print(stderr, "ERROR: tenants do not accept configuration options before API version 720.\n"); + return false; + } + loop { tr->setOption(FDBTransactionOptions::SPECIAL_KEY_SPACE_ENABLE_WRITES); try { @@ -149,13 +165,13 @@ CommandFactory createTenantFactory("createtenant", "Creates a new tenant in the cluster with the specified name.")); // deletetenant command -ACTOR Future deleteTenantCommandActor(Reference db, std::vector tokens) { +ACTOR Future deleteTenantCommandActor(Reference db, std::vector tokens, int apiVersion) { if (tokens.size() != 2) { printUsage(tokens[0]); return false; } - state Key tenantNameKey = tenantMapSpecialKeyRange.begin.withSuffix(tokens[1]); + state Key tenantNameKey = tenantMapSpecialKeyRange(apiVersion).begin.withSuffix(tokens[1]); state Reference tr = db->createTransaction(); state bool doneExistenceCheck = false; @@ -198,7 +214,7 @@ CommandFactory deleteTenantFactory( "Deletes a tenant from the cluster. Deletion will be allowed only if the specified tenant contains no data.")); // listtenants command -ACTOR Future listTenantsCommandActor(Reference db, std::vector tokens) { +ACTOR Future listTenantsCommandActor(Reference db, std::vector tokens, int apiVersion) { if (tokens.size() > 4) { printUsage(tokens[0]); return false; @@ -226,8 +242,8 @@ ACTOR Future listTenantsCommandActor(Reference db, std::vector< } } - state Key beginTenantKey = tenantMapSpecialKeyRange.begin.withSuffix(beginTenant); - state Key endTenantKey = tenantMapSpecialKeyRange.begin.withSuffix(endTenant); + state Key beginTenantKey = tenantMapSpecialKeyRange(apiVersion).begin.withSuffix(beginTenant); + state Key endTenantKey = tenantMapSpecialKeyRange(apiVersion).begin.withSuffix(endTenant); state Reference tr = db->createTransaction(); loop { @@ -247,8 +263,9 @@ ACTOR Future listTenantsCommandActor(Reference db, std::vector< int index = 0; for (auto tenant : tenants) { - fmt::print( - " {}. {}\n", ++index, printable(tenant.key.removePrefix(tenantMapSpecialKeyRange.begin)).c_str()); + fmt::print(" {}. {}\n", + ++index, + printable(tenant.key.removePrefix(tenantMapSpecialKeyRange(apiVersion).begin)).c_str()); } return true; @@ -279,7 +296,7 @@ ACTOR Future getTenantCommandActor(Reference db, std::vector tr = db->createTransaction(); loop { diff --git a/fdbcli/fdbcli.actor.cpp b/fdbcli/fdbcli.actor.cpp index 26f4a8469c..d51adcb241 100644 --- a/fdbcli/fdbcli.actor.cpp +++ b/fdbcli/fdbcli.actor.cpp @@ -1909,14 +1909,14 @@ ACTOR Future cli(CLIOptions opt, LineNoise* plinenoise) { } if (tokencmp(tokens[0], "createtenant")) { - bool _result = wait(makeInterruptable(createTenantCommandActor(db, tokens))); + bool _result = wait(makeInterruptable(createTenantCommandActor(db, tokens, opt.apiVersion))); if (!_result) is_error = true; continue; } if (tokencmp(tokens[0], "deletetenant")) { - bool _result = wait(makeInterruptable(deleteTenantCommandActor(db, tokens))); + bool _result = wait(makeInterruptable(deleteTenantCommandActor(db, tokens, opt.apiVersion))); if (!_result) is_error = true; else if (tenantName.present() && tokens[1] == tenantName.get()) { @@ -1928,7 +1928,7 @@ ACTOR Future cli(CLIOptions opt, LineNoise* plinenoise) { } if (tokencmp(tokens[0], "listtenants")) { - bool _result = wait(makeInterruptable(listTenantsCommandActor(db, tokens))); + bool _result = wait(makeInterruptable(listTenantsCommandActor(db, tokens, opt.apiVersion))); if (!_result) is_error = true; continue; @@ -1942,6 +1942,12 @@ ACTOR Future cli(CLIOptions opt, LineNoise* plinenoise) { } if (tokencmp(tokens[0], "configuretenant")) { + if (opt.apiVersion < 720) { + fmt::print(stderr, "ERROR: tenants cannot be configured before API version 720.\n"); + is_error = true; + continue; + } + bool _result = wait(makeInterruptable(configureTenantCommandActor(db, tokens))); if (!_result) is_error = true; @@ -1949,6 +1955,12 @@ ACTOR Future cli(CLIOptions opt, LineNoise* plinenoise) { } if (tokencmp(tokens[0], "renametenant")) { + if (opt.apiVersion < 720) { + fmt::print(stderr, "ERROR: tenants cannot be renamed before API version 720.\n"); + is_error = true; + continue; + } + bool _result = wait(makeInterruptable(renameTenantCommandActor(db, tokens))); if (!_result) is_error = true; diff --git a/fdbcli/include/fdbcli/fdbcli.actor.h b/fdbcli/include/fdbcli/fdbcli.actor.h index 3b497b17d5..1ea649a805 100644 --- a/fdbcli/include/fdbcli/fdbcli.actor.h +++ b/fdbcli/include/fdbcli/fdbcli.actor.h @@ -166,11 +166,11 @@ ACTOR Future consistencyCheckCommandActor(Reference tr, // coordinators command ACTOR Future coordinatorsCommandActor(Reference db, std::vector tokens); // createtenant command -ACTOR Future createTenantCommandActor(Reference db, std::vector tokens); +ACTOR Future createTenantCommandActor(Reference db, std::vector tokens, int apiVersion); // datadistribution command ACTOR Future dataDistributionCommandActor(Reference db, std::vector tokens); // deletetenant command -ACTOR Future deleteTenantCommandActor(Reference db, std::vector tokens); +ACTOR Future deleteTenantCommandActor(Reference db, std::vector tokens, int apiVersion); // exclude command ACTOR Future excludeCommandActor(Reference db, std::vector tokens, Future warn); // expensive_data_check command @@ -196,7 +196,7 @@ ACTOR Future killCommandActor(Reference db, std::vector tokens, std::map>* address_interface); // listtenants command -ACTOR Future listTenantsCommandActor(Reference db, std::vector tokens); +ACTOR Future listTenantsCommandActor(Reference db, std::vector tokens, int apiVersion); // lock/unlock command ACTOR Future lockCommandActor(Reference db, std::vector tokens); ACTOR Future unlockDatabaseActor(Reference db, UID uid);