diff --git a/bindings/python/tests/fdbcli_tests.py b/bindings/python/tests/fdbcli_tests.py index e4a40b1141..552bba8f49 100755 --- a/bindings/python/tests/fdbcli_tests.py +++ b/bindings/python/tests/fdbcli_tests.py @@ -628,8 +628,9 @@ def tenants(logger): assert(len(json_output) == 2) assert('tenant' in json_output) assert(json_output['type'] == 'success') - assert(len(json_output['tenant']) == 3) + assert(len(json_output['tenant']) == 4) assert('id' in json_output['tenant']) + assert('encrypted' in json_output['tenant']) assert('prefix' in json_output['tenant']) assert(len(json_output['tenant']['prefix']) == 2) assert('base64' in json_output['tenant']['prefix']) @@ -649,8 +650,9 @@ def tenants(logger): assert(len(json_output) == 2) assert('tenant' in json_output) assert(json_output['type'] == 'success') - assert(len(json_output['tenant']) == 4) + assert(len(json_output['tenant']) == 5) assert('id' in json_output['tenant']) + assert('encrypted' in json_output['tenant']) assert('prefix' in json_output['tenant']) assert(json_output['tenant']['tenant_state'] == 'ready') assert('tenant_group' in json_output['tenant']) diff --git a/fdbclient/Tenant.cpp b/fdbclient/Tenant.cpp index f7d380a750..9c8c63f18e 100644 --- a/fdbclient/Tenant.cpp +++ b/fdbclient/Tenant.cpp @@ -71,11 +71,15 @@ TenantState TenantMapEntry::stringToTenantState(std::string stateStr) { } TenantMapEntry::TenantMapEntry() {} -TenantMapEntry::TenantMapEntry(int64_t id, TenantState tenantState) : tenantState(tenantState) { +TenantMapEntry::TenantMapEntry(int64_t id, TenantState tenantState, bool encrypted) + : tenantState(tenantState), encrypted(encrypted) { setId(id); } -TenantMapEntry::TenantMapEntry(int64_t id, TenantState tenantState, Optional<TenantGroupName> tenantGroup) - : tenantState(tenantState), tenantGroup(tenantGroup) { +TenantMapEntry::TenantMapEntry(int64_t id, + TenantState tenantState, + Optional<TenantGroupName> tenantGroup, + bool encrypted) + : tenantState(tenantState), tenantGroup(tenantGroup), encrypted(encrypted) { setId(id); } @@ -88,6 +92,7 @@ void TenantMapEntry::setId(int64_t id) { std::string TenantMapEntry::toJson(int apiVersion) const { json_spirit::mObject tenantEntry; tenantEntry["id"] = id; + tenantEntry["encrypted"] = encrypted; if (apiVersion >= 720 || apiVersion == Database::API_VERSION_LATEST) { json_spirit::mObject prefixObject; @@ -133,12 +138,12 @@ void TenantMapEntry::configure(Standalone<StringRef> parameter, Optional<Value> } TEST_CASE("/fdbclient/TenantMapEntry/Serialization") { - TenantMapEntry entry1(1, TenantState::READY); + TenantMapEntry entry1(1, TenantState::READY, false); ASSERT(entry1.prefix == "\x00\x00\x00\x00\x00\x00\x00\x01"_sr); TenantMapEntry entry2 = TenantMapEntry::decode(entry1.encode()); ASSERT(entry1.id == entry2.id && entry1.prefix == entry2.prefix); - TenantMapEntry entry3(std::numeric_limits<int64_t>::max(), TenantState::READY); + TenantMapEntry entry3(std::numeric_limits<int64_t>::max(), TenantState::READY, false); ASSERT(entry3.prefix == "\x7f\xff\xff\xff\xff\xff\xff\xff"_sr); TenantMapEntry entry4 = TenantMapEntry::decode(entry3.encode()); ASSERT(entry3.id == entry4.id && entry3.prefix == entry4.prefix); @@ -149,7 +154,7 @@ TEST_CASE("/fdbclient/TenantMapEntry/Serialization") { int64_t maxPlusOne = std::min<uint64_t>(UINT64_C(1) << bits, std::numeric_limits<int64_t>::max()); int64_t id = deterministicRandom()->randomInt64(min, maxPlusOne); - TenantMapEntry entry(id, TenantState::READY); + TenantMapEntry entry(id, TenantState::READY, false); int64_t bigEndianId = bigEndian64(id); ASSERT(entry.id == id && entry.prefix == StringRef(reinterpret_cast<uint8_t*>(&bigEndianId), 8)); diff --git a/fdbclient/include/fdbclient/CommitProxyInterface.h b/fdbclient/include/fdbclient/CommitProxyInterface.h index 4212bdf298..253e0e1f36 100644 --- a/fdbclient/include/fdbclient/CommitProxyInterface.h +++ b/fdbclient/include/fdbclient/CommitProxyInterface.h @@ -117,6 +117,7 @@ struct ClientDBInfo { Optional<Value> forward; std::vector<VersionHistory> history; UID clusterId; + bool isEncryptionEnabled = false; TenantMode tenantMode; @@ -130,7 +131,7 @@ struct ClientDBInfo { if constexpr (!is_fb_function<Archive>) { ASSERT(ar.protocolVersion().isValid()); } - serializer(ar, grvProxies, commitProxies, id, forward, history, tenantMode, clusterId); + serializer(ar, grvProxies, commitProxies, id, forward, history, tenantMode, clusterId, isEncryptionEnabled); } }; diff --git a/fdbclient/include/fdbclient/Tenant.h b/fdbclient/include/fdbclient/Tenant.h index 59cf7e83e3..7cce7dcb05 100644 --- a/fdbclient/include/fdbclient/Tenant.h +++ b/fdbclient/include/fdbclient/Tenant.h @@ -48,13 +48,14 @@ struct TenantMapEntry { Key prefix; TenantState tenantState = TenantState::READY; Optional<TenantGroupName> tenantGroup; + bool encrypted = false; constexpr static int PREFIX_SIZE = sizeof(id); public: TenantMapEntry(); - TenantMapEntry(int64_t id, TenantState tenantState); - TenantMapEntry(int64_t id, TenantState tenantState, Optional<TenantGroupName> tenantGroup); + TenantMapEntry(int64_t id, TenantState tenantState, bool encrypted); + TenantMapEntry(int64_t id, TenantState tenantState, Optional<TenantGroupName> tenantGroup, bool encrypted); void setId(int64_t id); std::string toJson(int apiVersion) const; @@ -69,7 +70,7 @@ public: template <class Ar> void serialize(Ar& ar) { - serializer(ar, id, tenantState, tenantGroup); + serializer(ar, id, tenantState, tenantGroup, encrypted); if constexpr (Ar::isDeserializing) { if (id >= 0) { prefix = idToPrefix(id); diff --git a/fdbclient/include/fdbclient/TenantSpecialKeys.actor.h b/fdbclient/include/fdbclient/TenantSpecialKeys.actor.h index d75691c413..7c9ccc7cc2 100644 --- a/fdbclient/include/fdbclient/TenantSpecialKeys.actor.h +++ b/fdbclient/include/fdbclient/TenantSpecialKeys.actor.h @@ -116,6 +116,7 @@ private: std::map<TenantGroupName, int>* tenantGroupNetTenantDelta) { state TenantMapEntry tenantEntry; tenantEntry.setId(tenantId); + tenantEntry.encrypted = ryw->getTransactionState()->cx->clientInfo->get().isEncryptionEnabled; for (auto const& [name, value] : configMutations) { tenantEntry.configure(name, value); diff --git a/fdbserver/ClusterController.actor.cpp b/fdbserver/ClusterController.actor.cpp index fb74b294cf..485d3ab3cb 100644 --- a/fdbserver/ClusterController.actor.cpp +++ b/fdbserver/ClusterController.actor.cpp @@ -248,6 +248,7 @@ ACTOR Future<Void> clusterWatchDatabase(ClusterControllerData* cluster, dbInfo.latencyBandConfig = db->serverInfo->get().latencyBandConfig; dbInfo.myLocality = db->serverInfo->get().myLocality; dbInfo.client = ClientDBInfo(); + dbInfo.client.isEncryptionEnabled = SERVER_KNOBS->ENABLE_ENCRYPTION; dbInfo.client.tenantMode = db->config.tenantMode; dbInfo.client.clusterId = db->serverInfo->get().client.clusterId; @@ -1011,7 +1012,8 @@ void clusterRegisterMaster(ClusterControllerData* self, RegisterMasterRequest co // Construct the client information if (db->clientInfo->get().commitProxies != req.commitProxies || db->clientInfo->get().grvProxies != req.grvProxies || - db->clientInfo->get().tenantMode != db->config.tenantMode || db->clientInfo->get().clusterId != req.clusterId) { + db->clientInfo->get().tenantMode != db->config.tenantMode || db->clientInfo->get().clusterId != req.clusterId || + db->clientInfo->get().isEncryptionEnabled != SERVER_KNOBS->ENABLE_ENCRYPTION) { TraceEvent("PublishNewClientInfo", self->id) .detail("Master", dbInfo.master.id()) .detail("GrvProxies", db->clientInfo->get().grvProxies) @@ -1021,11 +1023,13 @@ void clusterRegisterMaster(ClusterControllerData* self, RegisterMasterRequest co .detail("TenantMode", db->clientInfo->get().tenantMode.toString()) .detail("ReqTenantMode", db->config.tenantMode.toString()) .detail("ClusterId", db->clientInfo->get().clusterId) + .detail("EncryptionEnabled", SERVER_KNOBS->ENABLE_ENCRYPTION) .detail("ReqClusterId", req.clusterId); isChanged = true; // TODO why construct a new one and not just copy the old one and change proxies + id? ClientDBInfo clientInfo; clientInfo.id = deterministicRandom()->randomUniqueID(); + clientInfo.isEncryptionEnabled = SERVER_KNOBS->ENABLE_ENCRYPTION; clientInfo.commitProxies = req.commitProxies; clientInfo.grvProxies = req.grvProxies; clientInfo.tenantMode = db->config.tenantMode; diff --git a/fdbserver/Coordination.actor.cpp b/fdbserver/Coordination.actor.cpp index 2092a87fba..3f44412799 100644 --- a/fdbserver/Coordination.actor.cpp +++ b/fdbserver/Coordination.actor.cpp @@ -393,6 +393,7 @@ ACTOR Future<Void> leaderRegister(LeaderElectionRegInterface interf, Key key) { notify[i].send(newInfo); notify.clear(); ClientDBInfo outInfo; + outInfo.isEncryptionEnabled = SERVER_KNOBS->ENABLE_ENCRYPTION; outInfo.id = deterministicRandom()->randomUniqueID(); outInfo.forward = req.conn.toString(); clientData.clientInfo->set(CachedSerialization<ClientDBInfo>(outInfo)); @@ -632,6 +633,7 @@ ACTOR Future<Void> leaderServer(LeaderElectionRegInterface interf, Optional<LeaderInfo> forward = regs.getForward(req.clusterKey); if (forward.present()) { ClientDBInfo info; + info.isEncryptionEnabled = SERVER_KNOBS->ENABLE_ENCRYPTION; info.id = deterministicRandom()->randomUniqueID(); info.forward = forward.get().serializedInfo; req.reply.send(CachedSerialization<ClientDBInfo>(info)); diff --git a/fdbserver/TenantCache.actor.cpp b/fdbserver/TenantCache.actor.cpp index a7fdc79612..491dff1664 100644 --- a/fdbserver/TenantCache.actor.cpp +++ b/fdbserver/TenantCache.actor.cpp @@ -217,7 +217,7 @@ public: for (uint16_t i = 0; i < tenantCount; i++) { TenantName tenantName(format("%s_%08d", "ddtc_test_tenant", tenantNumber + i)); - TenantMapEntry tenant(tenantNumber + i, TenantState::READY); + TenantMapEntry tenant(tenantNumber + i, TenantState::READY, SERVER_KNOBS->ENABLE_ENCRYPTION); tenantCache.insert(tenantName, tenant); } @@ -245,7 +245,7 @@ public: for (uint16_t i = 0; i < tenantCount; i++) { TenantName tenantName(format("%s_%08d", "ddtc_test_tenant", tenantNumber + i)); - TenantMapEntry tenant(tenantNumber + i, TenantState::READY); + TenantMapEntry tenant(tenantNumber + i, TenantState::READY, SERVER_KNOBS->ENABLE_ENCRYPTION); tenantCache.insert(tenantName, tenant); } @@ -259,7 +259,7 @@ public: if (tenantOrdinal % staleTenantFraction != 0) { TenantName tenantName(format("%s_%08d", "ddtc_test_tenant", tenantOrdinal)); - TenantMapEntry tenant(tenantOrdinal, TenantState::READY); + TenantMapEntry tenant(tenantOrdinal, TenantState::READY, SERVER_KNOBS->ENABLE_ENCRYPTION); bool newTenant = tenantCache.update(tenantName, tenant); ASSERT(!newTenant); keepCount++; diff --git a/fdbserver/storageserver.actor.cpp b/fdbserver/storageserver.actor.cpp index 436436d344..33fe662e7a 100644 --- a/fdbserver/storageserver.actor.cpp +++ b/fdbserver/storageserver.actor.cpp @@ -4262,11 +4262,11 @@ bool rangeIntersectsAnyTenant(TenantPrefixIndex& prefixIndex, KeyRangeRef range, TEST_CASE("/fdbserver/storageserver/rangeIntersectsAnyTenant") { std::map<TenantName, TenantMapEntry> entries = { - std::make_pair("tenant0"_sr, TenantMapEntry(0, TenantState::READY)), - std::make_pair("tenant2"_sr, TenantMapEntry(2, TenantState::READY)), - std::make_pair("tenant3"_sr, TenantMapEntry(3, TenantState::READY)), - std::make_pair("tenant4"_sr, TenantMapEntry(4, TenantState::READY)), - std::make_pair("tenant6"_sr, TenantMapEntry(6, TenantState::READY)) + std::make_pair("tenant0"_sr, TenantMapEntry(0, TenantState::READY, SERVER_KNOBS->ENABLE_ENCRYPTION)), + std::make_pair("tenant2"_sr, TenantMapEntry(2, TenantState::READY, SERVER_KNOBS->ENABLE_ENCRYPTION)), + std::make_pair("tenant3"_sr, TenantMapEntry(3, TenantState::READY, SERVER_KNOBS->ENABLE_ENCRYPTION)), + std::make_pair("tenant4"_sr, TenantMapEntry(4, TenantState::READY, SERVER_KNOBS->ENABLE_ENCRYPTION)), + std::make_pair("tenant6"_sr, TenantMapEntry(6, TenantState::READY, SERVER_KNOBS->ENABLE_ENCRYPTION)) }; TenantPrefixIndex index; index.createNewVersion(1); diff --git a/fdbserver/tester.actor.cpp b/fdbserver/tester.actor.cpp index 52dec86acd..80e319cce5 100644 --- a/fdbserver/tester.actor.cpp +++ b/fdbserver/tester.actor.cpp @@ -1640,6 +1640,7 @@ ACTOR Future<Void> runTests(Reference<AsyncVar<Optional<struct ClusterController if (deterministicRandom()->coinflip()) { entry.tenantGroup = "TestTenantGroup"_sr; } + entry.encrypted = SERVER_KNOBS->ENABLE_ENCRYPTION; TraceEvent("CreatingTenant").detail("Tenant", tenant).detail("TenantGroup", entry.tenantGroup); tenantFutures.push_back(success(TenantAPI::createTenant(cx.getReference(), tenant, entry))); } diff --git a/fdbserver/workloads/FuzzApiCorrectness.actor.cpp b/fdbserver/workloads/FuzzApiCorrectness.actor.cpp index 27000783b7..a2cd623fa2 100644 --- a/fdbserver/workloads/FuzzApiCorrectness.actor.cpp +++ b/fdbserver/workloads/FuzzApiCorrectness.actor.cpp @@ -24,6 +24,7 @@ #include <sstream> #include "fdbclient/FDBOptions.g.h" +#include "fdbserver/Knobs.h" #include "fdbserver/TesterInterface.actor.h" #include "fdbclient/GenericManagementAPI.actor.h" #include "fdbclient/TenantManagement.actor.h" @@ -240,6 +241,7 @@ struct FuzzApiCorrectnessWorkload : TestWorkload { if (i < self->numTenants) { TenantMapEntry entry; entry.tenantGroup = self->getTenantGroup(i); + entry.encrypted = SERVER_KNOBS->ENABLE_ENCRYPTION; tenantFutures.push_back(::success(TenantAPI::createTenant(cx.getReference(), tenantName, entry))); self->createdTenants.insert(tenantName); } diff --git a/fdbserver/workloads/TenantManagementWorkload.actor.cpp b/fdbserver/workloads/TenantManagementWorkload.actor.cpp index 49b97929c9..052bdc94ac 100644 --- a/fdbserver/workloads/TenantManagementWorkload.actor.cpp +++ b/fdbserver/workloads/TenantManagementWorkload.actor.cpp @@ -40,10 +40,11 @@ struct TenantManagementWorkload : TestWorkload { int64_t id; Optional<TenantGroupName> tenantGroup; bool empty; + bool encrypted; TenantData() : id(-1), empty(true) {} - TenantData(int64_t id, Optional<TenantGroupName> tenantGroup, bool empty) - : id(id), tenantGroup(tenantGroup), empty(empty) {} + TenantData(int64_t id, Optional<TenantGroupName> tenantGroup, bool empty, bool encrypted) + : id(id), tenantGroup(tenantGroup), empty(empty), encrypted(encrypted) {} }; struct TenantGroupData { @@ -209,6 +210,11 @@ struct TenantManagementWorkload : TestWorkload { TenantMapEntry entry; entry.tenantGroup = self->chooseTenantGroup(true); + if (operationType == OperationType::SPECIAL_KEYS) { + entry.encrypted = SERVER_KNOBS->ENABLE_ENCRYPTION; + } else { + entry.encrypted = deterministicRandom()->coinflip(); + } if (self->createdTenants.count(tenant)) { alreadyExists = true; @@ -266,7 +272,7 @@ struct TenantManagementWorkload : TestWorkload { // Update our local tenant state to include the newly created one self->maxId = entry.get().id; self->createdTenants[tenantItr->first] = - TenantData(entry.get().id, tenantItr->second.tenantGroup, true); + TenantData(entry.get().id, tenantItr->second.tenantGroup, true, tenantItr->second.encrypted); // If this tenant has a tenant group, create or update the entry for it if (tenantItr->second.tenantGroup.present()) { @@ -582,10 +588,12 @@ struct TenantManagementWorkload : TestWorkload { std::string tenantStateStr; std::string base64TenantGroup; std::string printableTenantGroup; + bool encrypted; jsonDoc.get("id", id); jsonDoc.get("prefix.base64", base64Prefix); jsonDoc.get("prefix.printable", printablePrefix); + jsonDoc.get("prefix.encrypted", encrypted); prefix = base64::decoder::from_string(base64Prefix); ASSERT(prefix == unprintable(printablePrefix)); @@ -600,7 +608,7 @@ struct TenantManagementWorkload : TestWorkload { tenantGroup = TenantGroupNameRef(tenantGroupStr); } - TenantMapEntry entry(id, TenantState::READY, tenantGroup); + TenantMapEntry entry(id, TenantState::READY, tenantGroup, encrypted); ASSERT(entry.prefix == prefix); return entry; } @@ -1127,6 +1135,7 @@ struct TenantManagementWorkload : TestWorkload { ASSERT(localItr != self->createdTenants.end()); ASSERT(dataItr->first == localItr->first); ASSERT(dataItr->second.tenantGroup == localItr->second.tenantGroup); + ASSERT(dataItr->second.encrypted == localItr->second.encrypted); checkTenants.push_back(checkTenantContents(cx, self, dataItr->first, localItr->second)); lastTenant = dataItr->first;