Merge pull request #7714 from sfc-gh-nwijetunga/nim/tenant-encryption-property
Encryption as a tenant property
This commit is contained in:
commit
3e45b6657c
|
@ -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'])
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue