Skip to content

Commit

Permalink
Merge pull request #303 from wazuh/enhancement/296-update-hardware-in…
Browse files Browse the repository at this point in the history
…ventory-format

Adapts hardware information data to the ECS
  • Loading branch information
vikman90 authored Nov 14, 2024
2 parents dfe28c4 + d99f3b0 commit 9d6e3ac
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 54 deletions.
3 changes: 2 additions & 1 deletion src/modules/inventory/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ get_filename_component(COMMON_FOLDER ${SRC_FOLDER}/common/ ABSOLUTE)
find_package(cJSON CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
find_package(OpenSSL REQUIRED)
find_package(Boost REQUIRED COMPONENTS asio)
find_package(Boost REQUIRED COMPONENTS asio beast)

add_library(Inventory
src/inventory.cpp
Expand Down Expand Up @@ -51,6 +51,7 @@ target_link_libraries(Inventory
MultiTypeQueue
ModuleCommand
Boost::asio
Boost::beast
PRIVATE
Logger
cjson
Expand Down
4 changes: 4 additions & 0 deletions src/modules/inventory/include/inventory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class Inventory {

std::string GetCreateStatement() const;
nlohmann::json GetOSData();
nlohmann::json EcsHardwareData(const nlohmann::json& originalData);
nlohmann::json GetHardwareData();
nlohmann::json GetNetworkData();
nlohmann::json GetPortsData();
Expand All @@ -69,6 +70,9 @@ class Inventory {
void ShowConfig();
cJSON * Dump();
static void LogErrorInventory(const std::string& log);
nlohmann::json EcsData(const nlohmann::json& data, const std::string& table);
std::string GetPrimaryKeys(const nlohmann::json& data, const std::string& table);
std::string CalculateBase64Id(const nlohmann::json& data, const std::string& table);

const std::string m_moduleName {"inventory"};
std::shared_ptr<ISysInfo> m_spInfo;
Expand Down
13 changes: 7 additions & 6 deletions src/modules/inventory/src/inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,20 @@ void Inventory::SetPushMessageFunction(const std::function<int(Message)>& pushMe
void Inventory::SendDeltaEvent(const std::string& data) {

const auto jsonData = nlohmann::json::parse(data);
auto metadata = nlohmann::json::object();

std::string dataType;
if (jsonData.contains("type") ) {
dataType = jsonData["type"].get<std::string>();
}
metadata["module"] = Name();
metadata["type"] = jsonData["type"];
metadata["operation"] = jsonData["operation"];
metadata["id"] = jsonData["id"];

const Message statefulMessage{ MessageType::STATEFUL, jsonData, Name(), dataType };
const Message statefulMessage{ MessageType::STATEFUL, jsonData["data"], Name(), jsonData["type"], metadata.dump() };

if(!m_pushMessage(statefulMessage)) {
LogWarn("Stateful event can't be pushed into the message queue: {}", data);
}
else {
LogTrace("Stateful event queued: {}, dataType {}", data, dataType);
LogTrace("Stateful event queued: {}, metadata {}", data, metadata.dump());
}
}

Expand Down
106 changes: 68 additions & 38 deletions src/modules/inventory/src/inventoryImp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stringHelper.h>
#include <hashHelper.h>
#include <timeHelper.h>
#include <boost/beast/core/detail/base64.hpp>

constexpr std::chrono::seconds INVENTORY_DEFAULT_INTERVAL { 3600 };

Expand All @@ -15,12 +16,12 @@ constexpr auto QUEUE_SIZE
static const std::map<ReturnTypeCallback, std::string> OPERATION_MAP
{
// LCOV_EXCL_START
{MODIFIED, "MODIFIED"},
{DELETED, "DELETED"},
{INSERTED, "INSERTED"},
{MAX_ROWS, "MAX_ROWS"},
{DB_ERROR, "DB_ERROR"},
{SELECTED, "SELECTED"},
{MODIFIED, "modified"},
{DELETED, "deleted"},
{INSERTED, "create"},
{MAX_ROWS, "max_rows"},
{DB_ERROR, "db_error"},
{SELECTED, "selected"},
// LCOV_EXCL_STOP
};

Expand Down Expand Up @@ -48,7 +49,7 @@ constexpr auto OS_SQL_STATEMENT

constexpr auto HW_SQL_STATEMENT
{
R"(CREATE TABLE hwinfo (
R"(CREATE TABLE hardware (
board_serial TEXT,
cpu_name TEXT,
cpu_cores INTEGER,
Expand Down Expand Up @@ -204,7 +205,7 @@ constexpr auto HOTFIXES_TABLE { "hotfixes" };
constexpr auto PORTS_TABLE { "ports" };
constexpr auto PROCESSES_TABLE { "processes" };
constexpr auto OS_TABLE { "osinfo" };
constexpr auto HW_TABLE { "hwinfo" };
constexpr auto HW_TABLE { "hardware" };


static std::string GetItemId(const nlohmann::json& item, const std::vector<std::string>& idFields)
Expand Down Expand Up @@ -239,25 +240,6 @@ static std::string GetItemChecksum(const nlohmann::json& item)
return Utils::asciiToHex(hash.hash());
}

static void RemoveKeysWithEmptyValue(nlohmann::json& input)
{
for (auto& data : input)
{
for (auto it = data.begin(); it != data.end(); )
{
if (it.value().type() == nlohmann::detail::value_t::string &&
it.value().get_ref<const std::string&>().empty())
{
it = data.erase(it);
}
else
{
++it;
}
}
}
}

static bool IsElementDuplicated(const nlohmann::json& input, const std::pair<std::string, std::string>& keyValue)
{
const auto it
Expand All @@ -270,6 +252,36 @@ static bool IsElementDuplicated(const nlohmann::json& input, const std::pair<std
return it != input.end();
}

nlohmann::json Inventory::EcsData(const nlohmann::json& data, const std::string& table)
{
nlohmann::json ret;
if(table == HW_TABLE)
{
ret = EcsHardwareData(data);
}
return ret;
}

std::string Inventory::GetPrimaryKeys([[maybe_unused]] const nlohmann::json& data, const std::string& table)
{
std::string ret;
if (table == HW_TABLE)
{
ret = data["observer"]["serial_number"];
}
return ret;
}

std::string Inventory::CalculateBase64Id(const nlohmann::json& data, const std::string& table)
{
std::string primaryKey = GetPrimaryKeys(data, table);
std::string baseId = Name() + ":" + table + ":" + primaryKey;
std::string idBase64;
idBase64.resize(boost::beast::detail::base64::encoded_size(baseId.size()));
boost::beast::detail::base64::encode(&idBase64[0], baseId.c_str(), baseId.size());
return idBase64;
}

void Inventory::NotifyChange(ReturnTypeCallback result, const nlohmann::json& data, const std::string& table)
{
if (DB_ERROR == result)
Expand All @@ -278,16 +290,17 @@ void Inventory::NotifyChange(ReturnTypeCallback result, const nlohmann::json& da
}
else if (m_notify && !m_stopping)
{

if (data.is_array())
{
for (const auto& item : data)
{
nlohmann::json msg;
msg["type"] = table;
msg["operation"] = OPERATION_MAP.at(result);
msg["data"] = item;
msg["data"] = EcsData(item, table);
msg["id"] = CalculateBase64Id(msg["data"], table);
msg["data"]["scan_time"] = m_scanTime;
RemoveKeysWithEmptyValue(msg["data"]);
const auto msgToSend{msg.dump()};
m_reportDiffFunction(msgToSend);
}
Expand All @@ -298,9 +311,9 @@ void Inventory::NotifyChange(ReturnTypeCallback result, const nlohmann::json& da
nlohmann::json msg;
msg["type"] = table;
msg["operation"] = OPERATION_MAP.at(result);
msg["data"] = data;
msg["data"] = EcsData(data, table);
msg["id"] = CalculateBase64Id(msg["data"], table);
msg["data"]["scan_time"] = m_scanTime;
RemoveKeysWithEmptyValue(msg["data"]);
const auto msgToSend{msg.dump()};
m_reportDiffFunction(msgToSend);
// LCOV_EXCL_STOP
Expand Down Expand Up @@ -408,11 +421,27 @@ void Inventory::Destroy()
lock.unlock();
}


nlohmann::json Inventory::EcsHardwareData(const nlohmann::json& originalData)
{
nlohmann::json ret;

ret["observer"]["serial_number"] = originalData.contains("board_serial") ? originalData["board_serial"] : "";
ret["host"]["cpu"]["name"] = originalData.contains("cpu_name") ? originalData["cpu_name"] : "";
ret["host"]["cpu"]["cores"] = originalData.contains("cpu_cores") ? originalData["cpu_cores"] : nlohmann::json(0);
ret["host"]["cpu"]["speed"] = originalData.contains("cpu_mhz") ? originalData["cpu_mhz"] : nlohmann::json(0);
ret["host"]["memory"]["total"] = originalData.contains("ram_total") ? originalData["ram_total"] : nlohmann::json(0);
ret["host"]["memory"]["free"] = originalData.contains("ram_free") ? originalData["ram_free"] : nlohmann::json(0);
ret["host"]["memory"]["used"]["percentage"] = originalData.contains("ram_usage") ? originalData["ram_usage"] : nlohmann::json(0);

return ret;
}


nlohmann::json Inventory::GetHardwareData()
{
nlohmann::json ret;
ret[0] = m_spInfo->hardware();
ret[0]["checksum"] = GetItemChecksum(ret[0]);
return ret;
}

Expand Down Expand Up @@ -772,12 +801,13 @@ void Inventory::Scan()
m_scanTime = Utils::getCurrentTimestamp();

TryCatchTask([&]() { ScanHardware(); });
TryCatchTask([&]() { ScanOs(); });
TryCatchTask([&]() { ScanNetwork(); });
TryCatchTask([&]() { ScanPackages(); });
TryCatchTask([&]() { ScanHotfixes(); });
TryCatchTask([&]() { ScanPorts(); });
TryCatchTask([&]() { ScanProcesses(); });
// TO DO: enable each scan once the ECS translation is done
//TryCatchTask([&]() { ScanOs(); });
//TryCatchTask([&]() { ScanNetwork(); });
//TryCatchTask([&]() { ScanPackages(); });
//TryCatchTask([&]() { ScanHotfixes(); });
//TryCatchTask([&]() { ScanPorts(); });
//TryCatchTask([&]() { ScanProcesses(); });
m_notify = true;
LogInfo("Evaluation finished.");
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/inventory/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ cmake_minimum_required(VERSION 3.22)

project(unit_tests)

add_subdirectory(inventoryImp)
#add_subdirectory(inventoryImp)
add_subdirectory(invNormalizer)
16 changes: 8 additions & 8 deletions src/modules/inventory/tests/inventoryImp/inventoryImp_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ TEST_F(InventoryImpTest, defaultCtor)

const auto expectedResult1
{
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hwinfo"})"
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hardware"})"
};
const auto expectedResult2
{
Expand Down Expand Up @@ -459,7 +459,7 @@ TEST_F(InventoryImpTest, noOs)

const auto expectedResult1
{
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hwinfo"})"
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hardware"})"
};
const auto expectedResult3
{
Expand Down Expand Up @@ -587,7 +587,7 @@ TEST_F(InventoryImpTest, noNetwork)

const auto expectedResult1
{
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hwinfo"})"
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hardware"})"
};
const auto expectedResult2
{
Expand Down Expand Up @@ -693,7 +693,7 @@ TEST_F(InventoryImpTest, noPackages)

const auto expectedResult1
{
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hwinfo"})"
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hardware"})"
};
const auto expectedResult2
{
Expand Down Expand Up @@ -821,7 +821,7 @@ TEST_F(InventoryImpTest, noPorts)

const auto expectedResult1
{
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hwinfo"})"
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hardware"})"
};
const auto expectedResult2
{
Expand Down Expand Up @@ -950,7 +950,7 @@ TEST_F(InventoryImpTest, noPortsAll)

const auto expectedResult1
{
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hwinfo"})"
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hardware"})"
};
const auto expectedResult2
{
Expand Down Expand Up @@ -1086,7 +1086,7 @@ TEST_F(InventoryImpTest, noProcesses)

const auto expectedResult1
{
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hwinfo"})"
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hardware"})"
};
const auto expectedResult2
{
Expand Down Expand Up @@ -1215,7 +1215,7 @@ TEST_F(InventoryImpTest, noHotfixes)

const auto expectedResult1
{
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hwinfo"})"
R"({"data":{"board_serial":"Intel Corporation","checksum":"af7b22eef8f5e06c04af4db49c9f8d1d28963918","cpu_MHz":2904,"cpu_cores":2,"cpu_name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","ram_free":2257872,"ram_total":4972208,"ram_usage":54},"operation":"INSERTED","type":"hardware"})"
};
const auto expectedResult2
{
Expand Down

0 comments on commit 9d6e3ac

Please sign in to comment.