My 11th 2023 update

This commit is contained in:
Ned Wright
2023-05-11 18:54:44 +00:00
parent 240f58217a
commit 29bd82d125
92 changed files with 9301 additions and 135 deletions

View File

@@ -21,6 +21,11 @@
#include "rest.h"
#include "cereal/external/rapidjson/document.h"
#include "customized_cereal_map.h"
#include "cereal/archives/json.hpp"
#include "cereal/types/vector.hpp"
#include "cereal/types/string.hpp"
#include <fstream>
using namespace std;
@@ -28,6 +33,31 @@ using namespace rapidjson;
USE_DEBUG_FLAG(D_ORCHESTRATOR);
// LCOV_EXCL_START Reason: WA for NSaaS upgrade
class TenantProfileMap
{
public:
void
load(const string &raw_value)
{
vector<string> tenants_and_profiles;
{
stringstream string_stream(raw_value);
cereal::JSONInputArchive archive(string_stream);
cereal::load(archive, tenants_and_profiles);
}
for (const auto &tenant_profile_pair : tenants_and_profiles) {
value.push_back(tenant_profile_pair);
}
}
const vector<string> & getValue() const { return value; }
private:
vector<string> value;
};
// LCOV_EXCL_STOP
class Downloader::Impl : Singleton::Provide<I_Downloader>::From<Downloader>
{
public:
@@ -51,6 +81,9 @@ public:
const string &service_name
) const override;
void createTenantProfileMap();
string getProfileFromMap(const string &tenant_id) const override;
private:
Maybe<string> downloadFileFromFogByHTTP(
const GetResourceFile &resourse_file,
@@ -74,6 +107,7 @@ private:
tuple<string, string> splitQuery(const string &query) const;
string vectorToPath(const vector<string> &vec) const;
string dir_path;
map<string, string> tenant_profile_map;
};
void
@@ -111,6 +145,42 @@ Downloader::Impl::downloadFileFromFog(
return file_path;
}
void
Downloader::Impl::createTenantProfileMap()
{
dbgFlow(D_ORCHESTRATOR) << "Creating a tenant-profile map from the agent settings";
tenant_profile_map.clear();
auto maybe_tenant_profile_map = getProfileAgentSetting<TenantProfileMap>("TenantProfileMap");
if (maybe_tenant_profile_map.ok()) {
dbgTrace(D_ORCHESTRATOR) << "Managed to read the TenantProfileMap agent settings";
TenantProfileMap tpm = maybe_tenant_profile_map.unpack();
for (const string &str : tpm.getValue()) {
string delimiter = ":";
string tenant = str.substr(0, str.find(delimiter));
string profile = str.substr(str.find(delimiter) + 1);
dbgTrace(D_ORCHESTRATOR)
<< "Loading into the map. Tenant: "
<< tenant
<< " Profile: "
<< profile;
tenant_profile_map[tenant] = profile;
}
} else {
dbgTrace(D_ORCHESTRATOR) << "Couldn't load the TenantProfileMap agent settings";
}
}
// LCOV_EXCL_START Reason: NSaaS old profiles support
string
Downloader::Impl::getProfileFromMap(const string &tenant_id) const
{
if (tenant_profile_map.find(tenant_id) == tenant_profile_map.end()) {
return "";
}
return tenant_profile_map.at(tenant_id);
}
// LCOV_EXCL_STOP
Maybe<map<pair<string, string>, string>>
Downloader::Impl::downloadVirtualFileFromFog(
const GetResourceFile &resourse_file,
@@ -130,8 +200,10 @@ Downloader::Impl::downloadVirtualFileFromFog(
Document document;
document.Parse(downloaded_data.unpack().c_str());
if (document.HasParseError()) return genError("JSON file is not valid.");
if (document.HasParseError()) {
dbgWarning(D_ORCHESTRATOR) << "JSON file is not valid";
return genError("JSON file is not valid.");
}
const Value &tenants_data = document[tenants_key.c_str()];
for (Value::ConstValueIterator itr = tenants_data.Begin(); itr != tenants_data.End(); ++itr) {
@@ -145,9 +217,21 @@ Downloader::Impl::downloadVirtualFileFromFog(
if (artifact_data != itr->MemberEnd()) {
auto profile_id_obj = itr->FindMember(profile_id_key.c_str());
if (profile_id_obj == itr->MemberEnd()) continue;
string profile_id;
if (profile_id_obj == itr->MemberEnd()) {
if (tenant_profile_map.count(tenant_id)) {
dbgWarning(D_ORCHESTRATOR)
<< "Forcing profile ID to be "
<< getProfileFromMap(tenant_id);
profile_id = getProfileFromMap(tenant_id);
} else {
dbgWarning(D_ORCHESTRATOR) << "Couldn't force profile ID";
continue;
}
}
string profile_id = profile_id_obj->value.GetString();
if (profile_id.empty()) profile_id = profile_id_obj->value.GetString();
dbgTrace(D_ORCHESTRATOR) << "Found a profile ID " << profile_id;
string file_path =
dir_path + "/" + resourse_file.getFileName() + "_" +
@@ -161,6 +245,9 @@ Downloader::Impl::downloadVirtualFileFromFog(
if (orchestration_tools->writeFile(buffer.GetString(), file_path)) {
res.insert({{tenant_id, profile_id}, file_path});
}
orchestration_tools->fillKeyInJson(file_path, "profileID", profile_id);
orchestration_tools->fillKeyInJson(file_path, "tenantID", tenant_id);
continue;
}
@@ -387,4 +474,5 @@ Downloader::preload()
registerExpectedConfiguration<string>("orchestration", "Default file download path");
registerExpectedConfiguration<string>("orchestration", "Self signed certificates acceptable");
registerExpectedConfiguration<bool>("orchestration", "Add tenant suffix");
registerConfigLoadCb([this]() { pimpl->createTenantProfileMap(); });
}

View File

@@ -345,6 +345,8 @@ TEST_F(DownloaderTest, download_virtual_policy)
EXPECT_CALL(mock_orchestration_tools, writeFile(tenant_0000_file, "/tmp/virtualPolicy_0000_profile_1234.download"))
.WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_tools, fillKeyInJson(_, _, _)).WillRepeatedly(Return());
EXPECT_CALL(mock_orchestration_tools, writeFile(tenant_1111_file, "/tmp/virtualPolicy_1111_profile_1235.download"))
.WillOnce(Return(true));
@@ -429,6 +431,8 @@ TEST_F(DownloaderTest, download_virtual_settings)
)
).WillOnce(Return(true));
EXPECT_CALL(mock_orchestration_tools, fillKeyInJson(_, _, _)).WillRepeatedly(Return());
stringstream file_path;
file_path << "/tmp/virtualSettings_4c721b40-85df-4364-be3d-303a10ee9789"
"_profile_4c721b40-85df-4364-be3d-303a10ee9780.download";

View File

@@ -40,6 +40,12 @@ public:
downloadFileFromURL,
Maybe<std::string>(const std::string &, const std::string &, Package::ChecksumTypes, const std::string &)
);
MOCK_CONST_METHOD1(
getProfileFromMap,
std::string(const std::string &)
);
};
#endif // __MOCK_DOWNLOADER_H__

View File

@@ -31,13 +31,6 @@ operator<<(std::ostream &os, const std::map<T, S> &)
return os;
}
template <typename T, typename S>
std::ostream &
operator<<(std::ostream &os, const Maybe<std::map<T, S>> &)
{
return os;
}
class MockOrchestrationTools
:
public Singleton::Provide<I_OrchestrationTools>::From<MockProvider<I_OrchestrationTools>>
@@ -56,6 +49,7 @@ public:
Maybe<std::map<std::string, std::string>>(const std::string &, const std::string &, const std::string &)
);
MOCK_CONST_METHOD1(doesFileExist, bool(const std::string &));
MOCK_CONST_METHOD3(fillKeyInJson, void(const std::string &, const std::string &, const std::string &));
MOCK_CONST_METHOD1(createDirectory, bool(const std::string &));
MOCK_CONST_METHOD1(doesDirectoryExist, bool(const std::string &));
MOCK_CONST_METHOD1(executeCmd, bool(const std::string &));

View File

@@ -1113,17 +1113,26 @@ private:
// Download virtual policy
bool is_empty = true;
GetResourceFile resource_v_policy_file(GetResourceFile::ResourceFileType::VIRTUAL_POLICY);
I_Downloader *downloader = Singleton::Consume<I_Downloader>::by<OrchestrationComp>();
for (const auto &tenant: *updated_policy_tenants) {
if (!tenant.getVersion().empty()) {
is_empty = false;
string profile_to_use = tenant.getProfileID().empty() ?
downloader->getProfileFromMap(tenant.getTenantID()) :
tenant.getProfileID();
dbgTrace(D_ORCHESTRATOR)
<< "Adding a tenant to the multi-tenant list. Tenant: "
<< tenant.getTenantID();
<< tenant.getTenantID()
<< " Profile: "
<< profile_to_use;
auto tenant_manager = Singleton::Consume<I_TenantManager>::by<OrchestrationComp>();
tenant_manager->addActiveTenantAndProfile(tenant.getTenantID(), tenant.getProfileID());
tenant_manager->addActiveTenantAndProfile(tenant.getTenantID(), profile_to_use);
resource_v_policy_file.addTenant(
tenant.getTenantID(),
tenant.getProfileID(),
profile_to_use,
tenant.getVersion(),
tenant.getChecksum()
);
@@ -1132,7 +1141,7 @@ private:
if (!is_empty) {
auto new_virtual_policy_files =
Singleton::Consume<I_Downloader>::by<OrchestrationComp>()->downloadVirtualFileFromFog(
downloader->downloadVirtualFileFromFog(
resource_v_policy_file,
I_OrchestrationTools::SELECTED_CHECKSUM_TYPE
);
@@ -1151,9 +1160,24 @@ private:
for (const auto &tenant: *updated_settings_tenants) {
if (!tenant.getVersion().empty()) {
is_empty = false;
string profile_to_use = tenant.getProfileID().empty() ?
downloader->getProfileFromMap(tenant.getTenantID()) :
tenant.getProfileID();
dbgTrace(D_ORCHESTRATOR)
<< "Handling virtual settings: Tenant ID: "
<< tenant.getTenantID()
<< ", Profile ID: "
<< profile_to_use
<< ", version: "
<< tenant.getVersion()
<< ", checksum: "
<< tenant.getChecksum();
resource_v_settings_file.addTenant(
tenant.getTenantID(),
tenant.getProfileID(),
profile_to_use,
tenant.getVersion(),
tenant.getChecksum()
);
@@ -1169,6 +1193,11 @@ private:
if (new_virtual_settings_files.ok()) {
for (const auto &tenant_file: *new_virtual_settings_files) {
auto tenant_profile = TenantProfilePair(tenant_file.first.first, tenant_file.first.second);
dbgTrace(D_ORCHESTRATOR)
<< "Downloaded a file from the FOG: Tenant ID: "
<< tenant_profile.getTenantId()
<< ", Profile ID: "
<< tenant_profile.getProfileId();
sorted_files[tenant_profile].push_back(tenant_file.second);
}
}

View File

@@ -45,6 +45,7 @@ public:
bool removeFile(const string &path) const override;
bool copyFile(const string &src_path, const string &dst_path) const override;
bool doesFileExist(const string &file_path) const override;
void fillKeyInJson(const string &filename, const string &_key, const string &_val) const override;
bool createDirectory(const string &directory_path) const override;
bool doesDirectoryExist(const string &dir_path) const override;
bool executeCmd(const string &cmd) const override;
@@ -78,6 +79,41 @@ checkExistence(const string &path, bool is_dir)
}
}
// LCOV_EXCL_START Reason: NSaaS upgrade WA
void
OrchestrationTools::Impl::fillKeyInJson(const string &filename, const string &_key, const string &_val) const
{
// Load the JSON file into a string
std::ifstream ifs(filename);
std::string jsonStr((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
dbgTrace(D_ORCHESTRATOR) << "Trying to parse " << filename;
// Parse the JSON string
Document doc;
doc.Parse(jsonStr.c_str());
// Check if the key exists
if (doc.HasMember(_key.c_str())) {
dbgTrace(D_ORCHESTRATOR) << _key << " already exists.";
return;
}
// Add the key with value
Value key(_key.c_str(), doc.GetAllocator());
Value val(_val.c_str(), doc.GetAllocator());
doc.AddMember(key, val, doc.GetAllocator());
// Write the modified JSON to a new file
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
doc.Accept(writer);
std::ofstream ofs(filename);
ofs << buffer.GetString() << std::endl;
dbgTrace(D_ORCHESTRATOR) << _key << " added with val " << _val;
}
// LCOV_EXCL_STOP
bool
OrchestrationTools::Impl::doesFileExist(const string &file_path) const
{

View File

@@ -265,14 +265,14 @@ TEST_F(OrchestrationMultitenancyTest, handle_virtual_resource)
EXPECT_CALL(mock_service_controller, getPolicyVersion())
.Times(2).WillRepeatedly(ReturnRef(first_policy_version));
vector<string> active_tenants = { "1236", "1235" };
set<string> active_tenants = { "1236", "1235" };
EXPECT_CALL(tenant_manager, fetchActiveTenants()).WillOnce(Return(active_tenants));
EXPECT_CALL(tenant_manager, addActiveTenantAndProfile("1235", "2311"));
EXPECT_CALL(tenant_manager, addActiveTenantAndProfile("1236", "2611"));
vector<string> first_tenant_profiles = { "2611" };
vector<string> second_tenant_profiles = { "2311"};
set<string> first_tenant_profiles = { "2611" };
set<string> second_tenant_profiles = { "2311"};
EXPECT_CALL(
tenant_manager,
fetchProfileIds("1236")).WillRepeatedly(Return(first_tenant_profiles)

View File

@@ -1466,8 +1466,8 @@ TEST_F(ServiceControllerTest, testMultitenantConfFiles)
make_pair("/etc/cp/conf/tenant2_profile_1235_policy.json", "")}
};
vector<string> ids = {"family1_id2"};
vector<string> empty_ids;
set<string> ids = {"family1_id2"};
set<string> empty_ids;
EXPECT_CALL(tenant_manager, getInstances("tenant1", "1234")).WillOnce(Return(ids));
EXPECT_CALL(tenant_manager, getInstances("tenant2", "1235")).WillOnce(Return(empty_ids));
@@ -1592,7 +1592,7 @@ TEST_F(ServiceControllerTest, cleanup_virtual_files)
"222222\n"
"333333\n";
vector<string> active_tenants = {
set<string> active_tenants = {
"222222"
};