mirror of
https://github.com/openappsec/openappsec.git
synced 2025-06-28 16:41:02 +03:00
Feb 22nd 2023 update
This commit is contained in:
parent
fd6239f44a
commit
38e6e1bbcf
@ -266,6 +266,10 @@ public:
|
||||
setActiveTenantAndProfile()
|
||||
{
|
||||
string container_id = inst_awareness->getFamilyID().unpack();
|
||||
if (container_id.empty()) {
|
||||
dbgWarning(D_NGINX_ATTACHMENT) << "Failed getting a family ID";
|
||||
return false;
|
||||
}
|
||||
dbgTrace(D_NGINX_ATTACHMENT) << "Found a family ID: " << container_id;
|
||||
|
||||
I_ShellCmd *shell_cmd = Singleton::Consume<I_ShellCmd>::by<NginxAttachment>();
|
||||
@ -273,58 +277,44 @@ public:
|
||||
string cmd =
|
||||
"docker inspect --format='{{.Name}}' " + container_id +
|
||||
" | awk -F'cp_nginx_gaia' '{print substr($2, index($2, \" \"))}'";
|
||||
auto maybe_tenant_id = shell_cmd->getExecOutput(cmd, 1000, false);
|
||||
auto maybe_tenant_profile_ids = shell_cmd->getExecOutput(cmd, 1000, false);
|
||||
dbgTrace(D_NGINX_ATTACHMENT) << "Checking for tenant and profile IDs with the command: " << cmd;
|
||||
|
||||
if (maybe_tenant_id.ok()) {
|
||||
if (!maybe_tenant_profile_ids.ok()) {
|
||||
dbgWarning(D_NGINX_ATTACHMENT)
|
||||
<< "Failed getting the tenant and progile IDs: "
|
||||
<< cmd
|
||||
<< ". Error :"
|
||||
<< maybe_tenant_profile_ids.getErr();
|
||||
|
||||
string tenant_id = *maybe_tenant_id;
|
||||
tenant_id.erase(remove(tenant_id.begin(), tenant_id.end(), '\n'), tenant_id.end());
|
||||
dbgTrace(D_NGINX_ATTACHMENT) << "The tenant ID found is :" << tenant_id;
|
||||
|
||||
static string region;
|
||||
if (region.empty()) {
|
||||
const char *env_region = getenv("CP_NSAAS_REGION");
|
||||
if (env_region) {
|
||||
region = env_region;
|
||||
} else {
|
||||
region = getProfileAgentSettingWithDefault<string>("eu-west-1", "accessControl.region");
|
||||
}
|
||||
dbgInfo(D_NGINX_ATTACHMENT) << "Resolved region is " << region;
|
||||
return false;
|
||||
}
|
||||
|
||||
string profile_id = Singleton::Consume<I_TenantManager>::by<NginxAttachment>()->getProfileId(
|
||||
tenant_id,
|
||||
region
|
||||
dbgWarning(D_NGINX_ATTACHMENT)
|
||||
<< "Parsing the tenant and profile IDs from the container name: "
|
||||
<< maybe_tenant_profile_ids.unpack();
|
||||
|
||||
string tenant_profile_ids = maybe_tenant_profile_ids.unpack();
|
||||
tenant_profile_ids.erase(
|
||||
remove(tenant_profile_ids.begin(), tenant_profile_ids.end(), '\n'), tenant_profile_ids.end()
|
||||
);
|
||||
|
||||
if (!profile_id.empty()) {
|
||||
size_t delimeter_pos = tenant_profile_ids.find("_");
|
||||
if (delimeter_pos == string::npos) {
|
||||
dbgWarning(D_NGINX_ATTACHMENT)
|
||||
<< "Couldn't parse tenant and profile IDs from the container name: "
|
||||
<< tenant_profile_ids;
|
||||
return false;
|
||||
}
|
||||
string tenant_id = tenant_profile_ids.substr(0, delimeter_pos);
|
||||
string profile_id = tenant_profile_ids.substr(delimeter_pos + 1);
|
||||
|
||||
i_env->setActiveTenantAndProfile(tenant_id, profile_id);
|
||||
dbgTrace(D_NGINX_ATTACHMENT)
|
||||
<< "NGINX attachment setting active context. Tenant ID: "
|
||||
<< tenant_id
|
||||
<< ", Profile ID: "
|
||||
<< profile_id
|
||||
<< ", Region: "
|
||||
<< region;
|
||||
return true;
|
||||
} else {
|
||||
dbgWarning(D_NGINX_ATTACHMENT)
|
||||
<< "Received an empty profile ID. Tenant ID: "
|
||||
<< tenant_id
|
||||
<< ", Region: "
|
||||
<< region;
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
dbgWarning(D_NGINX_ATTACHMENT)
|
||||
<< "Failed getting the tenant ID: "
|
||||
<< cmd
|
||||
<< ". Error :"
|
||||
<< maybe_tenant_id.getErr();
|
||||
|
||||
return false;
|
||||
}
|
||||
<< profile_id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -124,7 +124,10 @@ private:
|
||||
map<string, HealthCheckStatus> field_types_status;
|
||||
};
|
||||
|
||||
class setAgentUninstall : public ServerRest
|
||||
class SetAgentUninstall
|
||||
:
|
||||
public ServerRest,
|
||||
Singleton::Consume<I_AgentDetails>
|
||||
{
|
||||
public:
|
||||
void
|
||||
@ -132,11 +135,13 @@ public:
|
||||
{
|
||||
dbgTrace(D_ORCHESTRATOR) << "Send 'agent uninstall process started' log to fog";
|
||||
setConfiguration(false, "Logging", "Enable bulk of logs");
|
||||
string profile_id = Singleton::Consume<I_AgentDetails>::by<SetAgentUninstall>()->getProfileId();
|
||||
LogGen log (
|
||||
"Agent started uninstall process",
|
||||
Audience::INTERNAL,
|
||||
Severity::INFO,
|
||||
Priority::URGENT,
|
||||
LogField("profileId", profile_id),
|
||||
LogField("issuingEngine", "agentUninstallProvider"),
|
||||
Tags::ORCHESTRATOR
|
||||
);
|
||||
@ -167,7 +172,7 @@ public:
|
||||
auto rest = Singleton::Consume<I_RestApi>::by<OrchestrationComp>();
|
||||
rest->addRestCall<getStatusRest>(RestAction::SHOW, "orchestration-status");
|
||||
rest->addRestCall<AddProxyRest>(RestAction::ADD, "proxy");
|
||||
rest->addRestCall<setAgentUninstall>(RestAction::SET, "agent-uninstall");
|
||||
rest->addRestCall<SetAgentUninstall>(RestAction::SET, "agent-uninstall");
|
||||
// Main loop of the Orchestration.
|
||||
Singleton::Consume<I_MainLoop>::by<OrchestrationComp>()->addOneTimeRoutine(
|
||||
I_MainLoop::RoutineType::RealTime,
|
||||
|
@ -726,7 +726,7 @@ checkBinaryData(const std::string &line, bool binaryDataFound)
|
||||
|
||||
for (size_t i=0; i<line.size(); ++i) {
|
||||
unsigned char ch = (unsigned char)(line[i]);
|
||||
if (!isprint(ch)) {
|
||||
if (!isprint(ch) && (ch != '\r') && (ch != '\t') && (ch != '\n')) {
|
||||
nonPrintableCharsCount++;
|
||||
}
|
||||
}
|
||||
@ -735,7 +735,7 @@ checkBinaryData(const std::string &line, bool binaryDataFound)
|
||||
nonPrintableCharsCount << ", len=" << line.size();
|
||||
|
||||
// note: the threshold here is the same as used in base64 decoding (in function b64DecodeChunk)
|
||||
if (nonPrintableCharsCount * 3 >= line.size()) {
|
||||
if (nonPrintableCharsCount * 32 >= line.size()*10) {
|
||||
dbgTrace(D_WAAP_SAMPLE_SCAN) << "checkBinaryData('" << line << "'): detected BINARY DATA";
|
||||
binaryDataFound = true;
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ public:
|
||||
if (m_tag == "sourceip" || m_tag == "sourceidentifier") {
|
||||
m_isCidr = Waap::Util::isCIDR(m_value, m_cidr);
|
||||
}
|
||||
m_isOverrideResponse = (m_tag == "responsebody" || m_tag == "responseBody");
|
||||
|
||||
if (!m_isCidr) {
|
||||
// regex build may throw boost::regex_error
|
||||
@ -71,11 +72,13 @@ public:
|
||||
ar(cereal::make_nvp("operand1", *m_operand1));
|
||||
m_operand2 = std::make_shared<Match>();
|
||||
ar(cereal::make_nvp("operand2", *m_operand2));
|
||||
m_isOverrideResponse = m_operand1->m_isOverrideResponse || m_operand2->m_isOverrideResponse;
|
||||
}
|
||||
else if (m_op == "not") {
|
||||
// If op is "NOT" get one operand
|
||||
m_operand1 = std::make_shared<Match>();
|
||||
ar(cereal::make_nvp("operand1", *m_operand1));
|
||||
m_isOverrideResponse = m_operand1->m_isOverrideResponse;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -113,6 +116,10 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isOverrideResponse() const {
|
||||
return m_isOverrideResponse;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_op;
|
||||
std::shared_ptr<Match> m_operand1;
|
||||
@ -122,6 +129,7 @@ private:
|
||||
std::shared_ptr<boost::regex> m_valueRegex;
|
||||
Waap::Util::CIDRData m_cidr;
|
||||
bool m_isCidr;
|
||||
bool m_isOverrideResponse;
|
||||
};
|
||||
|
||||
class Behavior
|
||||
@ -233,6 +241,9 @@ public:
|
||||
bool isChangingRequestData() const {
|
||||
return m_isChangingRequestData;
|
||||
}
|
||||
bool isOverrideResponse() const {
|
||||
return m_match.isOverrideResponse();
|
||||
}
|
||||
|
||||
const std::string &getId() const {
|
||||
return m_id;
|
||||
@ -251,6 +262,7 @@ public:
|
||||
Policy(_A &ar) {
|
||||
std::vector<Waap::Override::Rule> rules;
|
||||
ar(cereal::make_nvp("overrides", rules));
|
||||
m_isOverrideResponse = false;
|
||||
|
||||
for (std::vector<Waap::Override::Rule>::const_iterator it = rules.begin(); it != rules.end(); ++it) {
|
||||
const Waap::Override::Rule& rule = *it;
|
||||
@ -262,6 +274,7 @@ public:
|
||||
{
|
||||
m_ResponseOverrides.push_back(rule);
|
||||
}
|
||||
m_isOverrideResponse |= rule.isOverrideResponse();
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,9 +295,14 @@ public:
|
||||
dbgTrace(D_WAAP_OVERRIDE) << "Finished matching override rules.";
|
||||
}
|
||||
|
||||
bool isOverrideResponse() const {
|
||||
return m_isOverrideResponse;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Waap::Override::Rule> m_RequestOverrides; //overrides that change request data
|
||||
std::vector<Waap::Override::Rule> m_ResponseOverrides; //overrides that change response/log data
|
||||
bool m_isOverrideResponse;
|
||||
};
|
||||
|
||||
struct State {
|
||||
|
@ -99,6 +99,16 @@ bool WaapOverrideFunctor::operator()(const std::string& tag, const boost::regex&
|
||||
else if (tag == "paramlocation" || tag == "paramLocation") {
|
||||
return NGEN::Regex::regexMatch(__FILE__, __LINE__, waf2Transaction.getLocation().c_str(), what, rx);
|
||||
}
|
||||
else if (tag == "responsebody" || tag == "responseBody") {
|
||||
waf2Transaction.getResponseInspectReasons().setApplyOverride(true);
|
||||
if (!waf2Transaction.getResponseBody().empty()) {
|
||||
boost::smatch matcher;
|
||||
return NGEN::Regex::regexSearch(__FILE__, __LINE__,
|
||||
waf2Transaction.getResponseBody().c_str(), matcher, rx);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error & e) {
|
||||
dbgDebug(D_WAAP_OVERRIDE) << "RegEx match for tag " << tag << " failed due to: " << e.what();
|
||||
|
@ -24,7 +24,8 @@ openRedirect(false),
|
||||
errorDisclosure(false),
|
||||
errorLimiter(false),
|
||||
rateLimiting(false),
|
||||
collectResponseForLog(false)
|
||||
collectResponseForLog(false),
|
||||
applyOverride(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -36,8 +37,9 @@ ResponseInspectReasons::shouldInspect() const
|
||||
" ErrorDisclosure=" << errorDisclosure <<
|
||||
" RateLimiting=" << rateLimiting <<
|
||||
" ErrorLimiter=" << errorLimiter <<
|
||||
" collectResponseForLog=" << collectResponseForLog;
|
||||
return openRedirect || errorDisclosure || rateLimiting || errorLimiter || collectResponseForLog;
|
||||
" collectResponseForLog=" << collectResponseForLog <<
|
||||
" applyOverride=" << applyOverride;
|
||||
return openRedirect || errorDisclosure || rateLimiting || errorLimiter || collectResponseForLog || applyOverride;
|
||||
}
|
||||
|
||||
void
|
||||
@ -76,4 +78,18 @@ ResponseInspectReasons::setCollectResponseForLog(bool flag)
|
||||
collectResponseForLog = flag;
|
||||
}
|
||||
|
||||
void
|
||||
ResponseInspectReasons::setApplyOverride(bool flag)
|
||||
{
|
||||
dbgTrace(D_WAAP) << "Change ResponseInspectReasons(setApplyOverride) " << applyOverride << " to " <<
|
||||
flag;
|
||||
applyOverride = flag;
|
||||
}
|
||||
|
||||
bool
|
||||
ResponseInspectReasons::getApplyOverride(void)
|
||||
{
|
||||
return applyOverride;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,12 +24,15 @@ public:
|
||||
void setRateLimiting(bool flag);
|
||||
void setErrorLimiter(bool flag);
|
||||
void setCollectResponseForLog(bool flag);
|
||||
void setApplyOverride(bool flag);
|
||||
bool getApplyOverride(void);
|
||||
private:
|
||||
bool openRedirect;
|
||||
bool errorDisclosure;
|
||||
bool errorLimiter;
|
||||
bool rateLimiting;
|
||||
bool collectResponseForLog;
|
||||
bool applyOverride;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -2097,6 +2097,29 @@ bool Waf2Transaction::decideResponse()
|
||||
return false; // block
|
||||
}
|
||||
|
||||
|
||||
if (m_responseInspectReasons.getApplyOverride()) {
|
||||
WaapConfigApplication ngenSiteConfig;
|
||||
|
||||
dbgTrace(D_WAAP_OVERRIDE) << "Checking exceptions for response";
|
||||
if (WaapConfigApplication::getWaapSiteConfig(ngenSiteConfig)) {
|
||||
dbgTrace(D_WAAP)
|
||||
<< "Waf2Transaction::decideResponse(): got relevant Application configuration from the I/S";
|
||||
m_overrideState = getOverrideState(&ngenSiteConfig);
|
||||
// Apply overrides
|
||||
if (m_overrideState.bForceBlock) {
|
||||
dbgTrace(D_WAAP)
|
||||
<< "Waf2Transaction::decideResponse(): setting shouldBlock to true due to override";
|
||||
return false; // BLOCK
|
||||
}
|
||||
else if (m_overrideState.bForceException) {
|
||||
dbgTrace(D_WAAP)
|
||||
<< "Waf2Transaction::decideResponse(): setting shouldBlock to false due to override";
|
||||
return true; // PASS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_siteConfig) {
|
||||
const std::shared_ptr<Waap::Trigger::Policy> triggerPolicy = m_siteConfig->get_TriggerPolicy();
|
||||
if (!triggerPolicy) {
|
||||
|
@ -219,6 +219,8 @@ public:
|
||||
Waap::OpenRedirect::State &getOpenRedirectState() { return m_openRedirectState; }
|
||||
IWaapConfig* getSiteConfig() { return m_siteConfig; }
|
||||
void addNote(const std::string ¬e) { m_notes.push_back(note); }
|
||||
const std::string &getResponseBody(void) const { return m_response_body; }
|
||||
Waap::ResponseInspectReasons &getResponseInspectReasons(void) { return m_responseInspectReasons; }
|
||||
|
||||
private:
|
||||
int finalizeDecision(IWaapConfig *sitePolicy, bool shouldBlock);
|
||||
|
@ -556,6 +556,7 @@ Waap::Override::State Waf2Transaction::getOverrideState(IWaapConfig* sitePolicy)
|
||||
Waap::Override::State overrideState;
|
||||
std::shared_ptr<Waap::Override::Policy> overridePolicy = sitePolicy->get_OverridePolicy();
|
||||
if (overridePolicy) { // at first we will run request overrides (in order to set the source)
|
||||
m_responseInspectReasons.setApplyOverride(overridePolicy->isOverrideResponse());
|
||||
overrideState.applyOverride(*overridePolicy, WaapOverrideFunctor(*this), m_matchedOverrideIds, true);
|
||||
}
|
||||
|
||||
|
@ -971,6 +971,7 @@ bool decodeBase64Chunk(
|
||||
int acc_bits = 0; // how many bits are filled in acc
|
||||
int terminatorCharsSeen = 0; // whether '=' character was seen, and how many of them.
|
||||
uint32_t nonPrintableCharsCount = 0;
|
||||
uint32_t spacer_count = 0;
|
||||
|
||||
dbgTrace(D_WAAP) << "decodeBase64Chunk: value='" << value << "' match='" << string(it, end) << "'";
|
||||
|
||||
@ -1047,9 +1048,12 @@ bool decodeBase64Chunk(
|
||||
acc_bits -= 8;
|
||||
|
||||
// Count non-printable characters seen
|
||||
if (!isprint(code)) {
|
||||
if (!isprint(code) && (code != '\n') && (code != '\t')) {
|
||||
nonPrintableCharsCount++;
|
||||
}
|
||||
if (code == '\r') {
|
||||
spacer_count++;
|
||||
}
|
||||
|
||||
decoded += (char)code;
|
||||
}
|
||||
@ -1059,12 +1063,24 @@ bool decodeBase64Chunk(
|
||||
|
||||
// end of encoded sequence decoded.
|
||||
|
||||
dbgTrace(D_WAAP_BASE64) << "decodeBase64Chunk: decoded.size=" << decoded.size() <<
|
||||
", nonPrintableCharsCount=" << nonPrintableCharsCount << "; decoded='" << decoded << "'";
|
||||
dbgTrace(D_WAAP_BASE64)
|
||||
<< "decodeBase64Chunk: decoded.size="
|
||||
<< decoded.size()
|
||||
<< ", nonPrintableCharsCount="
|
||||
<< nonPrintableCharsCount
|
||||
<< ", spacer_count = "
|
||||
<< spacer_count
|
||||
<< ", decoded size = "
|
||||
<< decoded.size()
|
||||
<< "; decoded='"
|
||||
<< decoded << "'";
|
||||
|
||||
// Return success only if decoded.size>=5 and there are less than 10% of non-printable
|
||||
// characters in output.
|
||||
if (decoded.size() >= 5) {
|
||||
if (spacer_count > 1) {
|
||||
nonPrintableCharsCount = nonPrintableCharsCount - spacer_count + 1;
|
||||
}
|
||||
if (nonPrintableCharsCount * 10 < decoded.size()) {
|
||||
dbgTrace(D_WAAP_BASE64) << "decodeBase64Chunk: (decode/replace) decoded.size=" << decoded.size() <<
|
||||
", nonPrintableCharsCount=" << nonPrintableCharsCount << ": replacing with decoded data";
|
||||
@ -1074,6 +1090,8 @@ bool decodeBase64Chunk(
|
||||
", nonPrintableCharsCount=" << nonPrintableCharsCount;
|
||||
decoded.clear();
|
||||
}
|
||||
dbgTrace(D_WAAP_BASE64) << "returning true: successfully decoded."
|
||||
<< " Returns decoded data in \"decoded\" parameter";
|
||||
return true; // successfully decoded. Returns decoded data in "decoded" parameter
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,11 @@ public:
|
||||
|
||||
virtual std::chrono::microseconds getTimeoutVal() const = 0;
|
||||
|
||||
virtual std::string getProfileId(const std::string &tenant_id, const std::string ®ion) const = 0;
|
||||
virtual std::vector<std::string> getProfileId(
|
||||
const std::string &tenant_id,
|
||||
const std::string ®ion,
|
||||
const std::string &account_id = ""
|
||||
) const = 0;
|
||||
|
||||
private:
|
||||
friend class LoadNewTenants;
|
||||
|
@ -25,7 +25,10 @@ public:
|
||||
MOCK_CONST_METHOD2(areTenantAndProfileActive, bool(const std::string &, const std::string &));
|
||||
MOCK_METHOD2(addActiveTenantAndProfile, void(const std::string &, const std::string &));
|
||||
MOCK_METHOD2(deactivateTenant, void(const std::string &, const std::string &));
|
||||
MOCK_CONST_METHOD2(getProfileId, std::string(const std::string &, const std::string &));
|
||||
MOCK_CONST_METHOD3(
|
||||
getProfileId,
|
||||
std::vector<std::string>(const std::string &, const std::string &, const std::string &)
|
||||
);
|
||||
|
||||
MOCK_CONST_METHOD0(getTimeoutVal, std::chrono::microseconds());
|
||||
|
||||
|
@ -69,6 +69,7 @@ enum class AudienceTeam
|
||||
AGENT_INTELLIGENCE,
|
||||
CPVIEW_MONITORING,
|
||||
SIGNATURE_DEVELOPERS,
|
||||
FILE_UPLOAD,
|
||||
IDENTITY_AWARENESS,
|
||||
NONE,
|
||||
|
||||
@ -140,6 +141,7 @@ enum class IssuingEngine {
|
||||
AGENT_CORE,
|
||||
IOT_NEXT,
|
||||
SDWAN,
|
||||
FILE_UPLOAD,
|
||||
IDA_NEXT
|
||||
};
|
||||
|
||||
|
@ -257,6 +257,7 @@ TagAndEnumManagement::convertToString(const IssuingEngine &issuing_engine)
|
||||
case IssuingEngine::AGENT_CORE: return "Agent Core";
|
||||
case IssuingEngine::IOT_NEXT: return "iotNext";
|
||||
case IssuingEngine::SDWAN: return "sdwanGwSharing";
|
||||
case IssuingEngine::FILE_UPLOAD: return "fileUpload";
|
||||
case IssuingEngine::IDA_NEXT: return "quantumMetaNotifyIdn";
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,46 @@ using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_TENANT_MANAGER);
|
||||
|
||||
class AccountRegionPair
|
||||
{
|
||||
public:
|
||||
void
|
||||
load(cereal::JSONInputArchive &ar)
|
||||
{
|
||||
ar(
|
||||
cereal::make_nvp("accountId", accountID),
|
||||
cereal::make_nvp("regionName", regionName)
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(const AccountRegionPair &other) const {
|
||||
return accountID < other.getAccountID() && regionName < other.getRegion();
|
||||
}
|
||||
|
||||
const string & getAccountID() const { return accountID; }
|
||||
const string & getRegion() const { return regionName; }
|
||||
|
||||
private:
|
||||
string accountID;
|
||||
string regionName;
|
||||
};
|
||||
|
||||
class AccountRegionSet
|
||||
{
|
||||
public:
|
||||
void
|
||||
load(cereal::JSONInputArchive &ar)
|
||||
{
|
||||
cereal::load(ar, account_region_map);
|
||||
}
|
||||
|
||||
const set<AccountRegionPair> & getAccoutRegionPairs() const { return account_region_map; }
|
||||
|
||||
private:
|
||||
set<AccountRegionPair> account_region_map;
|
||||
};
|
||||
|
||||
class TenantManager::Impl
|
||||
:
|
||||
Singleton::Provide<I_TenantManager>::From<TenantManager>
|
||||
@ -49,7 +89,7 @@ public:
|
||||
|
||||
chrono::microseconds getTimeoutVal() const override;
|
||||
|
||||
string getProfileId(const string &tenant_id, const string ®ion) const override;
|
||||
vector<string> getProfileId(const string &tenant_id, const string ®ion, const string &account) const override;
|
||||
|
||||
void
|
||||
addInstance(const string &tenant_id, const string &profile_id, const string &instace_id)
|
||||
@ -338,12 +378,13 @@ TenantManager::Impl::getProfileIds(const string &_tenant_id) const
|
||||
return tenant_id.profile_ids.get();
|
||||
}
|
||||
|
||||
string
|
||||
TenantManager::Impl::getProfileId(const string &tenant_id, const string ®ion) const
|
||||
|
||||
vector<string>
|
||||
TenantManager::Impl::getProfileId(const string &tenant_id, const string ®ion, const string &account_id = "") const
|
||||
{
|
||||
if (region.empty()) {
|
||||
dbgWarning(D_TENANT_MANAGER) << "Can't find the profile ID. Region is empty";
|
||||
return "";
|
||||
return vector<string>();
|
||||
}
|
||||
|
||||
vector<string> profile_ids = fetchProfileIds(tenant_id);
|
||||
@ -352,21 +393,35 @@ TenantManager::Impl::getProfileId(const string &tenant_id, const string ®ion)
|
||||
|
||||
auto i_env = Singleton::Consume<I_Environment>::by<TenantManager>();
|
||||
auto unset_tenant_on_exit = make_scope_exit([&]() { i_env->unsetActiveTenantAndProfile(); });
|
||||
|
||||
vector<string> profiles_to_return;
|
||||
for (const string &profile_id : profile_ids) {
|
||||
string account_dbg = account_id.empty() ? "" : (" in the account " + account_id);
|
||||
dbgDebug(D_TENANT_MANAGER)
|
||||
<< "Checking if the profile ID: "
|
||||
<< profile_id
|
||||
<< " corresponds to the tenant ID: "
|
||||
<< tenant_id
|
||||
<< " and the region "
|
||||
<< region;
|
||||
<< region
|
||||
<< account_dbg;
|
||||
|
||||
i_env->setActiveTenantAndProfile(tenant_id, profile_id);
|
||||
|
||||
auto maybe_account_region_set = getSetting<AccountRegionSet>("accountRegionSet");
|
||||
if (maybe_account_region_set.ok()) {
|
||||
for (const AccountRegionPair &account : maybe_account_region_set.unpack().getAccoutRegionPairs()) {
|
||||
if (region == account.getRegion() && (account_id.empty() || account_id == account.getAccountID())) {
|
||||
dbgTrace(D_TENANT_MANAGER) << "Found a corresponding profile ID: " << profile_id;
|
||||
profiles_to_return.push_back(profile_id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
auto maybe_region = getSetting<string>("region");
|
||||
if (maybe_region.ok() && region == maybe_region.unpack()) {
|
||||
dbgDebug(D_TENANT_MANAGER) << "The region corresponds to profile ID " << profile_id;
|
||||
return profile_id;
|
||||
profiles_to_return.push_back(profile_id);
|
||||
return profiles_to_return;
|
||||
} else {
|
||||
if (maybe_region.ok()) {
|
||||
dbgTrace(D_TENANT_MANAGER)
|
||||
@ -375,13 +430,19 @@ TenantManager::Impl::getProfileId(const string &tenant_id, const string ®ion)
|
||||
<< " region "
|
||||
<< *maybe_region;
|
||||
} else {
|
||||
dbgDebug(D_TENANT_MANAGER) << "Failed to get region for profile ID " << profile_id;
|
||||
dbgDebug(D_TENANT_MANAGER) << "Failed to match profile ID by accountRegionSet or region";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbgWarning(D_TENANT_MANAGER) << "Found no profile ID for tenant " << tenant_id << " and region " << region;
|
||||
return "";
|
||||
if (!profiles_to_return.empty()) {
|
||||
dbgDebug(D_TENANT_MANAGER) << "Found " << profiles_to_return.size() << " profiles that correspond";
|
||||
return profiles_to_return;
|
||||
}
|
||||
|
||||
dbgWarning(D_TENANT_MANAGER) << "Found no corresponding profile ID";
|
||||
return vector<string>();
|
||||
}
|
||||
|
||||
void
|
||||
@ -520,5 +581,6 @@ TenantManager::preload()
|
||||
{
|
||||
registerExpectedConfiguration<uint32_t>("Tenant Manager", "Tenant timeout");
|
||||
registerExpectedConfiguration<string>("Tenant Manager", "Tenant manager type");
|
||||
registerExpectedSetting<AccountRegionSet>("accountRegionSet");
|
||||
registerExpectedSetting<string>("region");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user