Better API version handling for fdbcli tenant commands

This commit is contained in:
A.J. Beamon 2022-07-22 15:37:48 -07:00
parent f6e3019a10
commit 2b6f349649
3 changed files with 49 additions and 20 deletions

View File

@ -35,10 +35,21 @@
namespace fdb_cli { namespace fdb_cli {
const KeyRangeRef tenantMapSpecialKeyRange(LiteralStringRef("\xff\xff/management/tenant/map/"), const KeyRangeRef tenantMapSpecialKeyRange720("\xff\xff/management/tenant/map/"_sr,
LiteralStringRef("\xff\xff/management/tenant/map0")); "\xff\xff/management/tenant/map0"_sr);
const KeyRangeRef tenantConfigSpecialKeyRange(LiteralStringRef("\xff\xff/management/tenant/configure/"), const KeyRangeRef tenantConfigSpecialKeyRange("\xff\xff/management/tenant/configure/"_sr,
LiteralStringRef("\xff\xff/management/tenant/configure0")); "\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<std::map<Standalone<StringRef>, Optional<Value>>> Optional<std::map<Standalone<StringRef>, Optional<Value>>>
parseTenantConfiguration(std::vector<StringRef> const& tokens, int startIndex, bool allowUnset) { parseTenantConfiguration(std::vector<StringRef> const& tokens, int startIndex, bool allowUnset) {
@ -94,13 +105,13 @@ void applyConfiguration(Reference<ITransaction> tr,
} }
// createtenant command // createtenant command
ACTOR Future<bool> createTenantCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens) { ACTOR Future<bool> createTenantCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens, int apiVersion) {
if (tokens.size() < 2 || tokens.size() > 3) { if (tokens.size() < 2 || tokens.size() > 3) {
printUsage(tokens[0]); printUsage(tokens[0]);
return false; return false;
} }
state Key tenantNameKey = tenantMapSpecialKeyRange.begin.withSuffix(tokens[1]); state Key tenantNameKey = tenantMapSpecialKeyRange(apiVersion).begin.withSuffix(tokens[1]);
state Reference<ITransaction> tr = db->createTransaction(); state Reference<ITransaction> tr = db->createTransaction();
state bool doneExistenceCheck = false; state bool doneExistenceCheck = false;
@ -111,6 +122,11 @@ ACTOR Future<bool> createTenantCommandActor(Reference<IDatabase> db, std::vector
return false; 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 { loop {
tr->setOption(FDBTransactionOptions::SPECIAL_KEY_SPACE_ENABLE_WRITES); tr->setOption(FDBTransactionOptions::SPECIAL_KEY_SPACE_ENABLE_WRITES);
try { try {
@ -149,13 +165,13 @@ CommandFactory createTenantFactory("createtenant",
"Creates a new tenant in the cluster with the specified name.")); "Creates a new tenant in the cluster with the specified name."));
// deletetenant command // deletetenant command
ACTOR Future<bool> deleteTenantCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens) { ACTOR Future<bool> deleteTenantCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens, int apiVersion) {
if (tokens.size() != 2) { if (tokens.size() != 2) {
printUsage(tokens[0]); printUsage(tokens[0]);
return false; return false;
} }
state Key tenantNameKey = tenantMapSpecialKeyRange.begin.withSuffix(tokens[1]); state Key tenantNameKey = tenantMapSpecialKeyRange(apiVersion).begin.withSuffix(tokens[1]);
state Reference<ITransaction> tr = db->createTransaction(); state Reference<ITransaction> tr = db->createTransaction();
state bool doneExistenceCheck = false; 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.")); "Deletes a tenant from the cluster. Deletion will be allowed only if the specified tenant contains no data."));
// listtenants command // listtenants command
ACTOR Future<bool> listTenantsCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens) { ACTOR Future<bool> listTenantsCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens, int apiVersion) {
if (tokens.size() > 4) { if (tokens.size() > 4) {
printUsage(tokens[0]); printUsage(tokens[0]);
return false; return false;
@ -226,8 +242,8 @@ ACTOR Future<bool> listTenantsCommandActor(Reference<IDatabase> db, std::vector<
} }
} }
state Key beginTenantKey = tenantMapSpecialKeyRange.begin.withSuffix(beginTenant); state Key beginTenantKey = tenantMapSpecialKeyRange(apiVersion).begin.withSuffix(beginTenant);
state Key endTenantKey = tenantMapSpecialKeyRange.begin.withSuffix(endTenant); state Key endTenantKey = tenantMapSpecialKeyRange(apiVersion).begin.withSuffix(endTenant);
state Reference<ITransaction> tr = db->createTransaction(); state Reference<ITransaction> tr = db->createTransaction();
loop { loop {
@ -247,8 +263,9 @@ ACTOR Future<bool> listTenantsCommandActor(Reference<IDatabase> db, std::vector<
int index = 0; int index = 0;
for (auto tenant : tenants) { for (auto tenant : tenants) {
fmt::print( fmt::print(" {}. {}\n",
" {}. {}\n", ++index, printable(tenant.key.removePrefix(tenantMapSpecialKeyRange.begin)).c_str()); ++index,
printable(tenant.key.removePrefix(tenantMapSpecialKeyRange(apiVersion).begin)).c_str());
} }
return true; return true;
@ -279,7 +296,7 @@ ACTOR Future<bool> getTenantCommandActor(Reference<IDatabase> db, std::vector<St
} }
state bool useJson = tokens.size() == 3; state bool useJson = tokens.size() == 3;
state Key tenantNameKey = tenantMapSpecialKeyRange.begin.withSuffix(tokens[1]); state Key tenantNameKey = tenantMapSpecialKeyRange(apiVersion).begin.withSuffix(tokens[1]);
state Reference<ITransaction> tr = db->createTransaction(); state Reference<ITransaction> tr = db->createTransaction();
loop { loop {

View File

@ -1909,14 +1909,14 @@ ACTOR Future<int> cli(CLIOptions opt, LineNoise* plinenoise) {
} }
if (tokencmp(tokens[0], "createtenant")) { if (tokencmp(tokens[0], "createtenant")) {
bool _result = wait(makeInterruptable(createTenantCommandActor(db, tokens))); bool _result = wait(makeInterruptable(createTenantCommandActor(db, tokens, opt.apiVersion)));
if (!_result) if (!_result)
is_error = true; is_error = true;
continue; continue;
} }
if (tokencmp(tokens[0], "deletetenant")) { if (tokencmp(tokens[0], "deletetenant")) {
bool _result = wait(makeInterruptable(deleteTenantCommandActor(db, tokens))); bool _result = wait(makeInterruptable(deleteTenantCommandActor(db, tokens, opt.apiVersion)));
if (!_result) if (!_result)
is_error = true; is_error = true;
else if (tenantName.present() && tokens[1] == tenantName.get()) { else if (tenantName.present() && tokens[1] == tenantName.get()) {
@ -1928,7 +1928,7 @@ ACTOR Future<int> cli(CLIOptions opt, LineNoise* plinenoise) {
} }
if (tokencmp(tokens[0], "listtenants")) { if (tokencmp(tokens[0], "listtenants")) {
bool _result = wait(makeInterruptable(listTenantsCommandActor(db, tokens))); bool _result = wait(makeInterruptable(listTenantsCommandActor(db, tokens, opt.apiVersion)));
if (!_result) if (!_result)
is_error = true; is_error = true;
continue; continue;
@ -1942,6 +1942,12 @@ ACTOR Future<int> cli(CLIOptions opt, LineNoise* plinenoise) {
} }
if (tokencmp(tokens[0], "configuretenant")) { 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))); bool _result = wait(makeInterruptable(configureTenantCommandActor(db, tokens)));
if (!_result) if (!_result)
is_error = true; is_error = true;
@ -1949,6 +1955,12 @@ ACTOR Future<int> cli(CLIOptions opt, LineNoise* plinenoise) {
} }
if (tokencmp(tokens[0], "renametenant")) { 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))); bool _result = wait(makeInterruptable(renameTenantCommandActor(db, tokens)));
if (!_result) if (!_result)
is_error = true; is_error = true;

View File

@ -166,11 +166,11 @@ ACTOR Future<bool> consistencyCheckCommandActor(Reference<ITransaction> tr,
// coordinators command // coordinators command
ACTOR Future<bool> coordinatorsCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens); ACTOR Future<bool> coordinatorsCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens);
// createtenant command // createtenant command
ACTOR Future<bool> createTenantCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens); ACTOR Future<bool> createTenantCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens, int apiVersion);
// datadistribution command // datadistribution command
ACTOR Future<bool> dataDistributionCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens); ACTOR Future<bool> dataDistributionCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens);
// deletetenant command // deletetenant command
ACTOR Future<bool> deleteTenantCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens); ACTOR Future<bool> deleteTenantCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens, int apiVersion);
// exclude command // exclude command
ACTOR Future<bool> excludeCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens, Future<Void> warn); ACTOR Future<bool> excludeCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens, Future<Void> warn);
// expensive_data_check command // expensive_data_check command
@ -196,7 +196,7 @@ ACTOR Future<bool> killCommandActor(Reference<IDatabase> db,
std::vector<StringRef> tokens, std::vector<StringRef> tokens,
std::map<Key, std::pair<Value, ClientLeaderRegInterface>>* address_interface); std::map<Key, std::pair<Value, ClientLeaderRegInterface>>* address_interface);
// listtenants command // listtenants command
ACTOR Future<bool> listTenantsCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens); ACTOR Future<bool> listTenantsCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens, int apiVersion);
// lock/unlock command // lock/unlock command
ACTOR Future<bool> lockCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens); ACTOR Future<bool> lockCommandActor(Reference<IDatabase> db, std::vector<StringRef> tokens);
ACTOR Future<bool> unlockDatabaseActor(Reference<IDatabase> db, UID uid); ACTOR Future<bool> unlockDatabaseActor(Reference<IDatabase> db, UID uid);