From 9b707d39c7db7f556bd616fd921b48e9030120e0 Mon Sep 17 00:00:00 2001 From: ncvicchi Date: Fri, 10 Jan 2025 01:06:15 -0300 Subject: [PATCH 01/10] feat: added removal of first scan flags when module is disabled --- src/modules/inventory/src/inventory.cpp | 49 +++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/modules/inventory/src/inventory.cpp b/src/modules/inventory/src/inventory.cpp index 5daded1a81..9f5fbf2408 100644 --- a/src/modules/inventory/src/inventory.cpp +++ b/src/modules/inventory/src/inventory.cpp @@ -11,6 +11,55 @@ void Inventory::Start() { if (!m_enabled) { LogInfo("Inventory module is disabled."); + DBSync::initialize(LogErrorInventory); + m_spDBSync = std::make_unique(HostType::AGENT, + DbEngineType::SQLITE3, + m_dbFilePath, + GetCreateStatement(), + DbManagement::PERSISTENT); + + m_hardwareFirstScan = ReadMetadata(hardwareFirstScanKey ).empty()? false:true; + m_systemFirstScan = ReadMetadata(systemFirstScanKey ).empty()? false:true; + m_networksFirstScan = ReadMetadata(networksFirstScanKey ).empty()? false:true; + m_packagesFirstScan = ReadMetadata(packagesFirstScanKey ).empty()? false:true; + m_portsFirstScan = ReadMetadata(portsFirstScanKey ).empty()? false:true; + m_portsAllFirstScan = ReadMetadata(portsAllFirstScanKey ).empty()? false:true; + m_processesFirstScan = ReadMetadata(processesFirstScanKey).empty()? false:true; + m_hotfixesFirstScan = ReadMetadata(hotfixesFirstScanKey ).empty()? false:true; + + if(hardwareFirstScanKey) + { + DeleteMetadata(hardwareFirstScanKey); + } + + if(systemFirstScanKey) + { + DeleteMetadata(systemFirstScanKey); + } + + if(networksFirstScanKey){ + DeleteMetadata(networksFirstScanKey); + } + + if(packagesFirstScanKey){ + DeleteMetadata(packagesFirstScanKey); + } + + if(portsFirstScanKey){ + DeleteMetadata(portsFirstScanKey); + } + + if(portsAllFirstScanKey){ + DeleteMetadata(portsAllFirstScanKey); + } + + if(processesFirstScanKey){ + DeleteMetadata(processesFirstScanKey); + } + + if(hotfixesFirstScanKey){ + DeleteMetadata(hotfixesFirstScanKey); + } return; } From ab356f1ad5ca51bee76c573561a0e39604d07bf3 Mon Sep 17 00:00:00 2001 From: Norberto Vicchi <69121070+ncvicchi@users.noreply.github.com> Date: Fri, 10 Jan 2025 10:26:45 -0300 Subject: [PATCH 02/10] Update inventory.cpp --- src/modules/inventory/src/inventory.cpp | 49 ---------------------- src/modules/inventory/src/inventoryImp.cpp | 13 +++++- 2 files changed, 11 insertions(+), 51 deletions(-) diff --git a/src/modules/inventory/src/inventory.cpp b/src/modules/inventory/src/inventory.cpp index 9f5fbf2408..5daded1a81 100644 --- a/src/modules/inventory/src/inventory.cpp +++ b/src/modules/inventory/src/inventory.cpp @@ -11,55 +11,6 @@ void Inventory::Start() { if (!m_enabled) { LogInfo("Inventory module is disabled."); - DBSync::initialize(LogErrorInventory); - m_spDBSync = std::make_unique(HostType::AGENT, - DbEngineType::SQLITE3, - m_dbFilePath, - GetCreateStatement(), - DbManagement::PERSISTENT); - - m_hardwareFirstScan = ReadMetadata(hardwareFirstScanKey ).empty()? false:true; - m_systemFirstScan = ReadMetadata(systemFirstScanKey ).empty()? false:true; - m_networksFirstScan = ReadMetadata(networksFirstScanKey ).empty()? false:true; - m_packagesFirstScan = ReadMetadata(packagesFirstScanKey ).empty()? false:true; - m_portsFirstScan = ReadMetadata(portsFirstScanKey ).empty()? false:true; - m_portsAllFirstScan = ReadMetadata(portsAllFirstScanKey ).empty()? false:true; - m_processesFirstScan = ReadMetadata(processesFirstScanKey).empty()? false:true; - m_hotfixesFirstScan = ReadMetadata(hotfixesFirstScanKey ).empty()? false:true; - - if(hardwareFirstScanKey) - { - DeleteMetadata(hardwareFirstScanKey); - } - - if(systemFirstScanKey) - { - DeleteMetadata(systemFirstScanKey); - } - - if(networksFirstScanKey){ - DeleteMetadata(networksFirstScanKey); - } - - if(packagesFirstScanKey){ - DeleteMetadata(packagesFirstScanKey); - } - - if(portsFirstScanKey){ - DeleteMetadata(portsFirstScanKey); - } - - if(portsAllFirstScanKey){ - DeleteMetadata(portsAllFirstScanKey); - } - - if(processesFirstScanKey){ - DeleteMetadata(processesFirstScanKey); - } - - if(hotfixesFirstScanKey){ - DeleteMetadata(hotfixesFirstScanKey); - } return; } diff --git a/src/modules/inventory/src/inventoryImp.cpp b/src/modules/inventory/src/inventoryImp.cpp index 2293e9f027..d315fe265a 100644 --- a/src/modules/inventory/src/inventoryImp.cpp +++ b/src/modules/inventory/src/inventoryImp.cpp @@ -140,7 +140,7 @@ constexpr auto PORTS_SQL_STATEMENT }; static const std::vector PORTS_ITEM_ID_FIELDS{"inode", "protocol", "local_ip", "local_port"}; -constexpr auto NETWORK_SQL_STATEMENT +constexpr auto NETWORKS_SQL_STATEMENT { R"(CREATE TABLE networks ( iface TEXT, @@ -168,6 +168,14 @@ constexpr auto NETWORK_SQL_STATEMENT ) WITHOUT ROWID;)" }; +constexpr auto METADATA_SQL_STATEMENT +{ + R"(CREATE TABLE metadata( + key TEXT, + value TEXT, + PRIMARY KEY (key)) WITHOUT ROWID;)" +}; + constexpr auto NETWORKS_TABLE { "networks" }; constexpr auto PACKAGES_TABLE { "packages" }; constexpr auto HOTFIXES_TABLE { "hotfixes" }; @@ -426,7 +434,8 @@ std::string Inventory::GetCreateStatement() const ret += HOTFIXES_SQL_STATEMENT; ret += PROCESSES_SQL_STATEMENT; ret += PORTS_SQL_STATEMENT; - ret += NETWORK_SQL_STATEMENT; + ret += NETWORKS_SQL_STATEMENT; + ret += METADATA_SQL_STATEMENT; return ret; } From 5cc4dce3056a01a9eb7f1bd4f814b93bbd1daea1 Mon Sep 17 00:00:00 2001 From: ncvicchi Date: Fri, 10 Jan 2025 12:54:19 -0300 Subject: [PATCH 03/10] fix: fixed inventory disabled scenario --- src/modules/inventory/src/inventory.cpp | 12 ++-- src/modules/inventory/src/inventoryImp.cpp | 65 +++++++++++++++++++++- 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/modules/inventory/src/inventory.cpp b/src/modules/inventory/src/inventory.cpp index 5daded1a81..dac77c1c48 100644 --- a/src/modules/inventory/src/inventory.cpp +++ b/src/modules/inventory/src/inventory.cpp @@ -14,10 +14,10 @@ void Inventory::Start() { return; } - LogInfo("Inventory module started."); - - ShowConfig(); - + if(m_enabled){ + LogInfo("Inventory module started."); + ShowConfig(); + } DBSync::initialize(LogErrorInventory); try @@ -33,7 +33,9 @@ void Inventory::Start() { LogErrorInventory(ex.what()); } - LogInfo("Inventory module stopped."); + if(m_enabled){ + LogInfo("Inventory module stopped."); + } } void Inventory::Setup(std::shared_ptr configurationParser) { diff --git a/src/modules/inventory/src/inventoryImp.cpp b/src/modules/inventory/src/inventoryImp.cpp index d315fe265a..20ac7bb1bb 100644 --- a/src/modules/inventory/src/inventoryImp.cpp +++ b/src/modules/inventory/src/inventoryImp.cpp @@ -459,7 +459,70 @@ void Inventory::Init(const std::shared_ptr& spInfo, m_spNormalizer = std::make_unique(normalizerConfigPath, normalizerType); } - SyncLoop(); + m_hardwareFirstScan = ReadMetadata(hardwareFirstScanKey ).empty()? false:true; + m_systemFirstScan = ReadMetadata(systemFirstScanKey ).empty()? false:true; + m_networksFirstScan = ReadMetadata(networksFirstScanKey ).empty()? false:true; + m_packagesFirstScan = ReadMetadata(packagesFirstScanKey ).empty()? false:true; + m_portsFirstScan = ReadMetadata(portsFirstScanKey ).empty()? false:true; + m_portsAllFirstScan = ReadMetadata(portsAllFirstScanKey ).empty()? false:true; + m_processesFirstScan = ReadMetadata(processesFirstScanKey).empty()? false:true; + m_hotfixesFirstScan = ReadMetadata(hotfixesFirstScanKey ).empty()? false:true; + + if(hardwareFirstScanKey && (!m_hardware || !m_enabled)) + { + DeleteMetadata(hardwareFirstScanKey); + m_hardwareFirstScan = false; + } + + if(systemFirstScanKey && (!m_system || !m_enabled)) + { + DeleteMetadata(systemFirstScanKey); + m_systemFirstScan = false; + } + + if(networksFirstScanKey && (!m_networks || !m_enabled)) + { + DeleteMetadata(networksFirstScanKey); + m_networksFirstScan = false; + + } + + if(packagesFirstScanKey && (!m_packages || !m_enabled)) + { + DeleteMetadata(packagesFirstScanKey); + m_packagesFirstScan = false; + } + + if(portsFirstScanKey && (!m_ports || !m_enabled)) + { + DeleteMetadata(portsFirstScanKey); + m_portsFirstScan = false; + } + + if(portsAllFirstScanKey && (!m_portsAll || !m_enabled)) + { + DeleteMetadata(portsAllFirstScanKey); + m_portsAllFirstScan = false; + } + if(processesFirstScanKey && (!m_processes || !m_enabled)) + { + DeleteMetadata(processesFirstScanKey); + m_processesFirstScan = false; + } + + if(hotfixesFirstScanKey && (!m_hotfixes || !m_enabled)) + { + DeleteMetadata(hotfixesFirstScanKey); + m_hotfixesFirstScan = false; + } + + if(m_enabled) + SyncLoop(); + else{ + Destroy(); + std::unique_lock lock{m_mutex}; + m_spDBSync.reset(nullptr); + } } void Inventory::Destroy() From 89f1f5bf26b77eb966af31f9e6f5720e7e2a1d21 Mon Sep 17 00:00:00 2001 From: nbertoldo Date: Mon, 13 Jan 2025 15:59:43 -0300 Subject: [PATCH 04/10] feat: add old_data to inventory events --- src/modules/inventory/include/inventory.hpp | 16 +- src/modules/inventory/src/inventoryImp.cpp | 430 ++++++++++++-------- 2 files changed, 267 insertions(+), 179 deletions(-) diff --git a/src/modules/inventory/include/inventory.hpp b/src/modules/inventory/include/inventory.hpp index 9beda2a6b2..d37104821b 100644 --- a/src/modules/inventory/include/inventory.hpp +++ b/src/modules/inventory/include/inventory.hpp @@ -54,13 +54,13 @@ class Inventory { void Destroy(); std::string GetCreateStatement() const; - nlohmann::json EcsProcessesData(const nlohmann::json& originalData); - nlohmann::json EcsSystemData(const nlohmann::json& originalData); - nlohmann::json EcsHotfixesData(const nlohmann::json& originalData); - nlohmann::json EcsHardwareData(const nlohmann::json& originalData); - nlohmann::json EcsPackageData(const nlohmann::json& originalData); - nlohmann::json EcsPortData(const nlohmann::json& originalData); - nlohmann::json EcsNetworkData(const nlohmann::json& originalData); + nlohmann::json EcsProcessesData(const nlohmann::json& originalData, bool createFields = true); + nlohmann::json EcsSystemData(const nlohmann::json& originalData, bool createFields = true); + nlohmann::json EcsHotfixesData(const nlohmann::json& originalData, bool createFields = true); + nlohmann::json EcsHardwareData(const nlohmann::json& originalData, bool createFields = true); + nlohmann::json EcsPackageData(const nlohmann::json& originalData, bool createFields = true); + nlohmann::json EcsPortData(const nlohmann::json& originalData, bool createFields = true); + nlohmann::json EcsNetworkData(const nlohmann::json& originalData, bool createFields = true); nlohmann::json GetOSData(); nlohmann::json GetHardwareData(); nlohmann::json GetNetworkData(); @@ -81,7 +81,7 @@ class Inventory { void ShowConfig(); cJSON * Dump() const; static void LogErrorInventory(const std::string& log); - nlohmann::json EcsData(const nlohmann::json& data, const std::string& table); + nlohmann::json EcsData(const nlohmann::json& data, const std::string& table, bool createFields = true); std::string GetPrimaryKeys(const nlohmann::json& data, const std::string& table); std::string CalculateHashId(const nlohmann::json& data, const std::string& table); diff --git a/src/modules/inventory/src/inventoryImp.cpp b/src/modules/inventory/src/inventoryImp.cpp index 20ac7bb1bb..3aaf968be5 100644 --- a/src/modules/inventory/src/inventoryImp.cpp +++ b/src/modules/inventory/src/inventoryImp.cpp @@ -224,36 +224,36 @@ static bool IsElementDuplicated(const nlohmann::json& input, const std::pair().size() <= MAX_ID_SIZE) @@ -341,7 +351,17 @@ void Inventory::NotifyChange(ReturnTypeCallback result, const nlohmann::json& da nlohmann::json msg; msg["type"] = table; msg["operation"] = OPERATION_MAP.at(result); - msg["data"] = EcsData(data, table); + + if(result == MODIFIED) + { + msg["data"] = EcsData(data["new"], table); + msg["old_data"] = EcsData(data["old"], table, false); + } + else + { + msg["data"] = EcsData(data, table); + } + msg["id"] = CalculateHashId(msg["data"], table); if (msg["id"].is_string() && msg["id"].get().size() <= MAX_ID_SIZE) @@ -384,6 +404,7 @@ void Inventory::UpdateChanges(const std::string& table, nlohmann::json input; input["table"] = table; input["data"] = values; + input["options"]["return_old_data"] = true; txn.syncTxnRow(input); txn.getDeletedRows(callback); } @@ -468,49 +489,49 @@ void Inventory::Init(const std::shared_ptr& spInfo, m_processesFirstScan = ReadMetadata(processesFirstScanKey).empty()? false:true; m_hotfixesFirstScan = ReadMetadata(hotfixesFirstScanKey ).empty()? false:true; - if(hardwareFirstScanKey && (!m_hardware || !m_enabled)) + if(m_hardwareFirstScan && (!m_hardware || !m_enabled)) { DeleteMetadata(hardwareFirstScanKey); m_hardwareFirstScan = false; } - if(systemFirstScanKey && (!m_system || !m_enabled)) + if(m_systemFirstScan && (!m_system || !m_enabled)) { DeleteMetadata(systemFirstScanKey); m_systemFirstScan = false; } - if(networksFirstScanKey && (!m_networks || !m_enabled)) + if(m_networksFirstScan && (!m_networks || !m_enabled)) { DeleteMetadata(networksFirstScanKey); m_networksFirstScan = false; } - if(packagesFirstScanKey && (!m_packages || !m_enabled)) + if(m_packagesFirstScan && (!m_packages || !m_enabled)) { DeleteMetadata(packagesFirstScanKey); m_packagesFirstScan = false; } - if(portsFirstScanKey && (!m_ports || !m_enabled)) + if(m_portsFirstScan && (!m_ports || !m_enabled)) { DeleteMetadata(portsFirstScanKey); m_portsFirstScan = false; } - if(portsAllFirstScanKey && (!m_portsAll || !m_enabled)) + if(m_portsAllFirstScan && (!m_portsAll || !m_enabled)) { DeleteMetadata(portsAllFirstScanKey); m_portsAllFirstScan = false; } - if(processesFirstScanKey && (!m_processes || !m_enabled)) + if(m_processesFirstScan && (!m_processes || !m_enabled)) { DeleteMetadata(processesFirstScanKey); m_processesFirstScan = false; } - if(hotfixesFirstScanKey && (!m_hotfixes || !m_enabled)) + if(m_hotfixesFirstScan && (!m_hotfixes || !m_enabled)) { DeleteMetadata(hotfixesFirstScanKey); m_hotfixesFirstScan = false; @@ -532,214 +553,244 @@ void Inventory::Destroy() m_cv.notify_all(); } - -nlohmann::json Inventory::EcsHardwareData(const nlohmann::json& originalData) +nlohmann::json Inventory::EcsHardwareData(const nlohmann::json& originalData, bool createFields) { nlohmann::json ret; - ret["observer"]["serial_number"] = (originalData.contains("board_serial") && !originalData["board_serial"].is_null()) ? - originalData["board_serial"] : EMPTY_VALUE; - ret["host"]["cpu"]["name"] = originalData.contains("cpu_name") ? originalData["cpu_name"] : UNKNOWN_VALUE; - ret["host"]["cpu"]["cores"] = originalData.contains("cpu_cores") ? originalData["cpu_cores"] : UNKNOWN_VALUE; - ret["host"]["cpu"]["speed"] = originalData.contains("cpu_mhz") ? originalData["cpu_mhz"] : UNKNOWN_VALUE; - ret["host"]["memory"]["total"] = originalData.contains("ram_total") ? originalData["ram_total"] : UNKNOWN_VALUE; - ret["host"]["memory"]["free"] = originalData.contains("ram_free") ? originalData["ram_free"] : UNKNOWN_VALUE; - ret["host"]["memory"]["used"]["percentage"] = originalData.contains("ram_usage") ? originalData["ram_usage"] : UNKNOWN_VALUE; + auto setField = [&](const std::string& keyPath, const std::string& jsonKey, const std::optional& defaultValue) { + if (createFields || originalData.contains(jsonKey)) { + nlohmann::json::json_pointer pointer(keyPath); + if (originalData.contains(jsonKey) && !originalData[jsonKey].is_null()) { + ret[pointer] = originalData[jsonKey]; + } else if (defaultValue.has_value()) { + ret[pointer] = *defaultValue; + } else { + ret[pointer] = nullptr; + } + } + }; + + setField("/observer/serial_number", "board_serial", EMPTY_VALUE); + setField("/host/cpu/name", "cpu_name", std::nullopt); + setField("/host/cpu/cores", "cpu_cores", std::nullopt); + setField("/host/cpu/speed", "cpu_mhz", std::nullopt); + setField("/host/memory/total", "ram_total", std::nullopt); + setField("/host/memory/free", "ram_free", std::nullopt); + setField("/host/memory/used/percentage", "ram_usage", std::nullopt); return ret; } -nlohmann::json Inventory::EcsSystemData(const nlohmann::json& originalData) +nlohmann::json Inventory::EcsSystemData(const nlohmann::json& originalData, bool createFields) { nlohmann::json ret; - ret["host"]["architecture"] = originalData.contains("architecture") ? originalData["architecture"] : UNKNOWN_VALUE; - ret["host"]["hostname"] = originalData.contains("hostname") ? originalData["hostname"] : UNKNOWN_VALUE; - ret["host"]["os"]["kernel"] = originalData.contains("os_build") ? originalData["os_build"] : UNKNOWN_VALUE; - ret["host"]["os"]["full"] = originalData.contains("os_codename") ? originalData["os_codename"] : UNKNOWN_VALUE; - ret["host"]["os"]["name"] = (originalData.contains("os_name") && !originalData["os_name"].is_null()) ? - originalData["os_name"] : EMPTY_VALUE; - ret["host"]["os"]["platform"] = originalData.contains("os_platform") ? originalData["os_platform"] : UNKNOWN_VALUE; - ret["host"]["os"]["version"]= originalData.contains("os_version") ? originalData["os_version"] : UNKNOWN_VALUE; - ret["host"]["os"]["type"]= originalData.contains("sysname") ? originalData["sysname"] : UNKNOWN_VALUE; + auto setField = [&](const std::string& keyPath, const std::string& jsonKey, const std::optional& defaultValue) { + if (createFields || originalData.contains(jsonKey)) { + nlohmann::json::json_pointer pointer(keyPath); + if (originalData.contains(jsonKey) && !originalData[jsonKey].is_null()) { + ret[pointer] = originalData[jsonKey]; + } else if (defaultValue.has_value()) { + ret[pointer] = *defaultValue; + } else { + ret[pointer] = nullptr; + } + } + }; + + setField("/host/architecture", "architecture", std::nullopt); + setField("/host/hostname", "hostname", std::nullopt); + setField("/host/os/kernel", "os_build", std::nullopt); + setField("/host/os/full", "os_codename", std::nullopt); + setField("/host/os/name", "os_name", EMPTY_VALUE); + setField("/host/os/platform", "os_platform", std::nullopt); + setField("/host/os/version", "os_version", std::nullopt); + setField("/host/os/type", "sysname", std::nullopt); return ret; } -nlohmann::json Inventory::EcsPackageData(const nlohmann::json& originalData) +nlohmann::json Inventory::EcsPackageData(const nlohmann::json& originalData, bool createFields) { nlohmann::json ret; - ret["package"]["architecture"] = (originalData.contains("architecture") && !originalData["architecture"].is_null()) ? - originalData["architecture"] : EMPTY_VALUE; - ret["package"]["description"] = originalData.contains("description") ? originalData["description"] : UNKNOWN_VALUE; - - if (originalData.contains("install_time") && !originalData["install_time"].empty() && !originalData["install_time"].is_null()) { - ret["package"]["installed"] = originalData["install_time"]; - } - else { - ret["package"]["installed"] = UNKNOWN_VALUE; - } + auto setField = [&](const std::string& keyPath, const std::string& jsonKey, const std::optional& defaultValue) { + if (createFields || originalData.contains(jsonKey)) { + nlohmann::json::json_pointer pointer(keyPath); + if (originalData.contains(jsonKey) && !originalData[jsonKey].is_null()) { + ret[pointer] = originalData[jsonKey]; + } else if (defaultValue.has_value()) { + ret[pointer] = *defaultValue; + } else { + ret[pointer] = nullptr; + } + } + }; - ret["package"]["name"] = (originalData.contains("name") && !originalData["name"].is_null()) ? - originalData["name"] : EMPTY_VALUE; - ret["package"]["path"] = (originalData.contains("location") && !originalData["location"].is_null()) ? - originalData["location"] : EMPTY_VALUE; - ret["package"]["size"] = originalData.contains("size") ? originalData["size"] : UNKNOWN_VALUE; - ret["package"]["type"] = (originalData.contains("format") && !originalData["format"].is_null()) ? - originalData["format"] : EMPTY_VALUE; - ret["package"]["version"] = (originalData.contains("version") && !originalData["version"].is_null()) ? - originalData["version"] : EMPTY_VALUE; + setField("/package/architecture", "architecture", EMPTY_VALUE); + setField("/package/description", "description", std::nullopt); + setField("/package/installed", "install_time", std::nullopt); + setField("/package/name", "name", EMPTY_VALUE); + setField("/package/path", "location", EMPTY_VALUE); + setField("/package/size", "size", std::nullopt); + setField("/package/type", "format", EMPTY_VALUE); + setField("/package/version", "version", EMPTY_VALUE); return ret; } -nlohmann::json Inventory::EcsProcessesData(const nlohmann::json& originalData) +nlohmann::json Inventory::EcsProcessesData(const nlohmann::json& originalData, bool createFields) { nlohmann::json ret; - ret["process"]["pid"] = (originalData.contains("pid") && !originalData["pid"].is_null()) ? - originalData["pid"] : EMPTY_VALUE; - ret["process"]["name"] = originalData.contains("name") ? originalData["name"] : UNKNOWN_VALUE; - ret["process"]["parent"]["pid"] = originalData.contains("ppid") ? originalData["ppid"] : UNKNOWN_VALUE; - ret["process"]["command_line"] = originalData.contains("cmd") ? originalData["cmd"] : UNKNOWN_VALUE; - ret["process"]["args"] = originalData.contains("argvs") ? originalData["argvs"] : UNKNOWN_VALUE; - ret["process"]["user"]["id"] = originalData.contains("euser") ? originalData["euser"] : UNKNOWN_VALUE; - ret["process"]["real_user"]["id"]= originalData.contains("ruser") ? originalData["ruser"] : UNKNOWN_VALUE; - ret["process"]["saved_user"]["id"]= originalData.contains("suser") ? originalData["suser"] : UNKNOWN_VALUE; - ret["process"]["group"]["id"]= originalData.contains("egroup") ? originalData["egroup"] : UNKNOWN_VALUE; - ret["process"]["real_group"]["id"]= originalData.contains("rgroup") ? originalData["rgroup"] : UNKNOWN_VALUE; - ret["process"]["saved_group"]["id"]= originalData.contains("sgroup") ? originalData["sgroup"] : UNKNOWN_VALUE; - - if (originalData.contains("start_time") && !originalData["start_time"].empty() && !originalData["start_time"].is_null()) { - ret["process"]["start"] = originalData["start_time"]; - } - else { - ret["process"]["start"] = UNKNOWN_VALUE; - } + auto setField = [&](const std::string& keyPath, const std::string& jsonKey, const std::optional& defaultValue) { + if (createFields || originalData.contains(jsonKey)) { + nlohmann::json::json_pointer pointer(keyPath); + if (originalData.contains(jsonKey) && !originalData[jsonKey].is_null()) { + ret[pointer] = originalData[jsonKey]; + } else if (defaultValue.has_value()) { + ret[pointer] = *defaultValue; + } else { + ret[pointer] = nullptr; + } + } + }; - ret["process"]["thread"]["id"]= originalData.contains("tgid") ? originalData["tgid"] : UNKNOWN_VALUE; - ret["process"]["tty"]["char_device"]["major"]= originalData.contains("tty") ? originalData["tty"] : UNKNOWN_VALUE; + setField("/process/pid", "pid", EMPTY_VALUE); + setField("/process/name", "name", std::nullopt); + setField("/process/parent/pid", "ppid", std::nullopt); + setField("/process/command_line", "cmd", std::nullopt); + setField("/process/args", "argvs", std::nullopt); + setField("/process/user/id", "euser", std::nullopt); + setField("/process/real_user/id", "ruser", std::nullopt); + setField("/process/saved_user/id", "suser", std::nullopt); + setField("/process/group/id", "egroup", std::nullopt); + setField("/process/real_group/id", "rgroup", std::nullopt); + setField("/process/saved_group/id", "sgroup", std::nullopt); + setField("/process/start", "start_time", std::nullopt); + setField("/process/thread/id", "tgid", std::nullopt); + setField("/process/tty/char_device/major", "tty", std::nullopt); return ret; } -nlohmann::json Inventory::EcsHotfixesData(const nlohmann::json& originalData){ +nlohmann::json Inventory::EcsHotfixesData(const nlohmann::json& originalData, bool createFields){ nlohmann::json ret; - ret["package"]["hotfix"]["name"] = (originalData.contains("hotfix") && !originalData["hotfix"].is_null()) ? - originalData["hotfix"] : EMPTY_VALUE; + if(createFields || originalData.contains("hotfix")) + { + ret["package"]["hotfix"]["name"] = (originalData.contains("hotfix") && !originalData["hotfix"].is_null()) ? + originalData["hotfix"] : EMPTY_VALUE; + } return ret; } -nlohmann::json Inventory::EcsPortData(const nlohmann::json& originalData) +nlohmann::json Inventory::EcsPortData(const nlohmann::json& originalData, bool createFields) { nlohmann::json ret; - ret["network"]["protocol"] = (originalData.contains("protocol") && !originalData["protocol"].is_null()) ? - originalData["protocol"] : EMPTY_VALUE; - - ret["source"]["ip"] = nlohmann::json::array(); - if (originalData.contains("local_ip") && - !originalData["local_ip"].empty() && - !originalData["local_ip"].is_null() && - originalData["local_ip"] != EMPTY_VALUE) - { - ret["source"]["ip"].push_back(originalData["local_ip"]); - } + auto setField = [&](const std::string& keyPath, const std::string& jsonKey, const std::optional& defaultValue) { + if (createFields || originalData.contains(jsonKey)) { + nlohmann::json::json_pointer pointer(keyPath); + if (originalData.contains(jsonKey) && !originalData[jsonKey].is_null()) { + ret[pointer] = originalData[jsonKey]; + } else if (defaultValue.has_value()) { + ret[pointer] = *defaultValue; + } else { + ret[pointer] = nullptr; + } + } + }; - ret["source"]["port"] = (originalData.contains("local_port") && !originalData["local_port"].is_null()) ? - originalData["local_port"] : EMPTY_VALUE; + auto setFieldArray = [&](const std::string& destPath, const std::string& sourceKey) { + if (createFields || originalData.contains(sourceKey)) { + nlohmann::json::json_pointer destPointer(destPath); + ret[destPointer.parent_pointer()][destPointer.back()] = nlohmann::json::array(); + nlohmann::json& destArray = ret[destPointer]; - ret["destination"]["ip"] = nlohmann::json::array(); - if (originalData.contains("remote_ip") && - !originalData["remote_ip"].empty() && - !originalData["remote_ip"].is_null() && - originalData["remote_ip"] != EMPTY_VALUE) - { - ret["destination"]["ip"].push_back(originalData["remote_ip"]); - } + if (originalData.contains(sourceKey) && + !originalData[sourceKey].empty() && + !originalData[sourceKey].is_null() && + originalData[sourceKey] != EMPTY_VALUE) + { + destArray.push_back(originalData[sourceKey]); + } + } + }; - ret["destination"]["port"] = originalData.contains("remote_port") ? originalData["remote_port"] : UNKNOWN_VALUE; - ret["host"]["network"]["egress"]["queue"] = originalData.contains("tx_queue") ? originalData["tx_queue"] : UNKNOWN_VALUE; - ret["host"]["network"]["ingress"]["queue"] = originalData.contains("rx_queue") ? originalData["rx_queue"] : UNKNOWN_VALUE; - ret["file"]["inode"] = (originalData.contains("inode") && !originalData["inode"].is_null()) ? - originalData["inode"] : EMPTY_VALUE; - ret["interface"]["state"] = originalData.contains("state") ? originalData["state"] : UNKNOWN_VALUE; - ret["process"]["pid"] = originalData.contains("pid") ? originalData["pid"] : UNKNOWN_VALUE; - ret["process"]["name"] = originalData.contains("process") ? originalData["process"] : UNKNOWN_VALUE; + setField("/network/protocol", "protocol", EMPTY_VALUE); + setFieldArray("/source/ip", "local_ip"); + setField("/source/port", "local_port", EMPTY_VALUE); + setFieldArray("/destination/ip", "remote_ip"); + setField("/destination/port", "remote_port", std::nullopt); + setField("/host/network/egress/queue", "tx_queue", std::nullopt); + setField("/host/network/ingress/queue", "rx_queue", std::nullopt); + setField("/file/inode", "inode", EMPTY_VALUE); + setField("/interface/state", "state", std::nullopt); + setField("/process/pid", "pid", std::nullopt); + setField("/process/name", "process", std::nullopt); return ret; } -nlohmann::json Inventory::EcsNetworkData(const nlohmann::json& originalData) +nlohmann::json Inventory::EcsNetworkData(const nlohmann::json& originalData, bool createFields) { nlohmann::json ret; - ret["host"]["ip"] = nlohmann::json::array(); - if (originalData.contains("address") && - !originalData["address"].empty() && - !originalData["address"].is_null() && - originalData["address"] != EMPTY_VALUE) - { - ret["host"]["ip"].push_back(originalData["address"]); - } - - ret["host"]["mac"] = originalData.contains("mac") ? originalData["mac"] : UNKNOWN_VALUE; - ret["host"]["network"]["egress"]["bytes"] = originalData.contains("tx_bytes") ? originalData["tx_bytes"] : UNKNOWN_VALUE; - ret["host"]["network"]["egress"]["packets"] = originalData.contains("tx_packets") ? originalData["tx_packets"] : UNKNOWN_VALUE; - ret["host"]["network"]["ingress"]["bytes"] = originalData.contains("rx_bytes") ? originalData["rx_bytes"] : UNKNOWN_VALUE; - ret["host"]["network"]["ingress"]["packets"] = originalData.contains("rx_packets") ? originalData["rx_packets"] : UNKNOWN_VALUE; - ret["host"]["network"]["egress"]["drops"] = originalData.contains("tx_dropped") ? originalData["tx_dropped"] : UNKNOWN_VALUE; - ret["host"]["network"]["egress"]["errors"] = originalData.contains("tx_errors") ? originalData["tx_errors"] : UNKNOWN_VALUE; - ret["host"]["network"]["ingress"]["drops"] = originalData.contains("rx_dropped") ? originalData["rx_dropped"] : UNKNOWN_VALUE; - ret["host"]["network"]["ingress"]["errors"] = originalData.contains("rx_errors") ? originalData["rx_errors"] : UNKNOWN_VALUE; - - ret["interface"]["mtu"] = originalData.contains("mtu") ? originalData["mtu"] : UNKNOWN_VALUE; - ret["interface"]["state"] = originalData.contains("state") ? originalData["state"] : UNKNOWN_VALUE; - ret["interface"]["type"] = (originalData.contains("iface_type") && !originalData["iface_type"].is_null()) ? - originalData["iface_type"] : EMPTY_VALUE; - - ret["network"]["netmask"] = nlohmann::json::array(); - if (originalData.contains("netmask") && - !originalData["netmask"].empty() && - !originalData["netmask"].is_null() && - originalData["netmask"] != EMPTY_VALUE) - { - ret["network"]["netmask"].push_back(originalData["netmask"]); - } + auto setField = [&](const std::string& keyPath, const std::string& jsonKey, const std::optional& defaultValue) { + if (createFields || originalData.contains(jsonKey)) { + nlohmann::json::json_pointer pointer(keyPath); + if (originalData.contains(jsonKey) && !originalData[jsonKey].is_null()) { + ret[pointer] = originalData[jsonKey]; + } else if (defaultValue.has_value()) { + ret[pointer] = *defaultValue; + } else { + ret[pointer] = nullptr; + } + } + }; - ret["network"]["gateway"] = nlohmann::json::array(); - if (originalData.contains("gateway") && - !originalData["gateway"].empty() && - !originalData["gateway"].is_null() && - originalData["gateway"] != EMPTY_VALUE) - { - ret["network"]["gateway"].push_back(originalData["gateway"]); - } + auto setFieldArray = [&](const std::string& destPath, const std::string& sourceKey) { + if (createFields || originalData.contains(sourceKey)) { + nlohmann::json::json_pointer destPointer(destPath); + ret[destPointer.parent_pointer()][destPointer.back()] = nlohmann::json::array(); + nlohmann::json& destArray = ret[destPointer]; - ret["network"]["broadcast"] = nlohmann::json::array(); - if (originalData.contains("broadcast") && - !originalData["broadcast"].empty() && - !originalData["broadcast"].is_null() && - originalData["broadcast"] != EMPTY_VALUE) - { - ret["network"]["broadcast"].push_back(originalData["broadcast"]); - } + if (originalData.contains(sourceKey) && + !originalData[sourceKey].empty() && + !originalData[sourceKey].is_null() && + originalData[sourceKey] != EMPTY_VALUE) + { + destArray.push_back(originalData[sourceKey]); + } + } + }; - ret["network"]["dhcp"] = originalData.contains("dhcp") ? originalData["dhcp"] : UNKNOWN_VALUE; - ret["network"]["type"] = (originalData.contains("proto_type") && !originalData["proto_type"].is_null()) ? - originalData["proto_type"] : EMPTY_VALUE; - ret["network"]["metric"] = originalData.contains("metric") ? originalData["metric"] : UNKNOWN_VALUE; + setFieldArray("/host/ip", "address"); + setField("/host/mac", "mac", std::nullopt); + setField("/host/network/egress/bytes", "tx_bytes", std::nullopt); + setField("/host/network/egress/packets", "tx_packets", std::nullopt); + setField("/host/network/ingress/bytes", "rx_bytes", std::nullopt); + setField("/host/network/ingress/packets", "rx_packets", std::nullopt); + setField("/host/network/egress/drops", "tx_dropped", std::nullopt); + setField("/host/network/egress/errors", "tx_errors", std::nullopt); + setField("/host/network/ingress/drops", "rx_dropped", std::nullopt); + setField("/host/network/ingress/errors", "rx_errors", std::nullopt); + setField("/interface/mtu", "mtu", std::nullopt); + setField("/interface/state", "state", std::nullopt); + setField("/interface/type", "iface_type", EMPTY_VALUE); + setFieldArray("/network/netmask", "netmask"); + setFieldArray("/network/gateway", "gateway"); + setFieldArray("/network/broadcast", "broadcast"); + setField("/network/dhcp", "dhcp", std::nullopt); + setField("/network/type", "proto_type", EMPTY_VALUE); + setField("/network/metric", "metric", std::nullopt); /* TODO this field should include http or https, it's related to an application not to a interface */ ret["network"]["protocol"] = UNKNOWN_VALUE; - - ret["observer"]["ingress"]["interface"]["alias"] = (originalData.contains("adapter") && !originalData["adapter"].is_null()) ? - originalData["adapter"] : EMPTY_VALUE; - ret["observer"]["ingress"]["interface"]["name"] = (originalData.contains("iface") && !originalData["iface"].is_null()) ? - originalData["iface"] : EMPTY_VALUE; + setField("/observer/ingress/interface/alias", "adapter", EMPTY_VALUE); + setField("/observer/ingress/interface/name", "iface", EMPTY_VALUE); return ret; } @@ -759,6 +810,11 @@ void Inventory::ScanHardware() const auto& hwData{GetHardwareData()}; UpdateChanges(HW_TABLE, hwData); LogTrace( "Ending hardware scan"); + + if(!m_hardwareFirstScan){ + WriteMetadata(hardwareFirstScanKey, Utils::getCurrentISO8601()); + m_hardwareFirstScan = true; + } } } @@ -777,6 +833,11 @@ void Inventory::ScanOs() const auto& osData{GetOSData()}; UpdateChanges(OS_TABLE, osData); LogTrace( "Ending os scan"); + + if(!m_systemFirstScan){ + WriteMetadata(systemFirstScanKey, Utils::getCurrentISO8601()); + m_systemFirstScan = true; + } } } @@ -876,6 +937,11 @@ void Inventory::ScanNetwork() } } + if(!m_networksFirstScan){ + WriteMetadata(networksFirstScanKey, Utils::getCurrentISO8601()); + m_networksFirstScan = true; + } + LogTrace( "Ending network scan"); } } @@ -913,11 +979,17 @@ void Inventory::ScanPackages() if (!rawData.empty()) { input["data"] = nlohmann::json::array( { rawData } ); + input["options"]["return_old_data"] = true; txn.syncTxnRow(input); } }); txn.getDeletedRows(callback); + if(!m_packagesFirstScan){ + WriteMetadata(packagesFirstScanKey, Utils::getCurrentISO8601()); + m_packagesFirstScan = true; + } + LogTrace( "Ending packages scan"); } } @@ -934,6 +1006,11 @@ void Inventory::ScanHotfixes() UpdateChanges(HOTFIXES_TABLE, hotfixes); } + if(!m_hotfixesFirstScan){ + WriteMetadata(hotfixesFirstScanKey, Utils::getCurrentISO8601()); + m_hotfixesFirstScan = true; + } + LogTrace( "Ending hotfixes scan"); } } @@ -1006,6 +1083,11 @@ void Inventory::ScanPorts() const auto& portsData { GetPortsData() }; UpdateChanges(PORTS_TABLE, portsData); LogTrace( "Ending ports scan"); + + if(!m_portsFirstScan){ + WriteMetadata(portsFirstScanKey, Utils::getCurrentISO8601()); + m_portsFirstScan = true; + } } } @@ -1036,11 +1118,17 @@ void Inventory::ScanProcesses() input["table"] = PROCESSES_TABLE; input["data"] = nlohmann::json::array( { rawData } ); + input["options"]["return_old_data"] = true; txn.syncTxnRow(input); }); txn.getDeletedRows(callback); + if(!m_processesFirstScan){ + WriteMetadata(processesFirstScanKey, Utils::getCurrentISO8601()); + m_processesFirstScan = true; + } + LogTrace( "Ending processes scan"); } } From 75b0ef649ebd63594789298474fec8ac9ad14b19 Mon Sep 17 00:00:00 2001 From: nbertoldo Date: Tue, 14 Jan 2025 16:51:54 -0300 Subject: [PATCH 05/10] fix: avoid report false positive deltas --- .../src/network/networkBSDWrapper.h | 16 +-- .../src/network/networkLinuxWrapper.h | 18 ++-- .../src/network/networkWindowsWrapper.h | 18 ++-- .../src/packages/appxWindowsWrapper.h | 10 +- .../data_provider/src/packages/brewWrapper.h | 16 +-- .../src/packages/macportsWrapper.h | 16 +-- .../src/packages/packageLinuxParserHelper.h | 32 +++--- .../packages/packageLinuxRpmParserHelper.h | 8 +- .../packageLinuxRpmParserHelperLegacy.h | 18 ++-- .../src/packages/packagesNPM.hpp | 16 +-- .../src/packages/packagesPYPI.hpp | 16 +-- .../data_provider/src/packages/pkgWrapper.h | 10 +- .../data_provider/src/ports/portBSDWrapper.h | 8 +- .../src/ports/portLinuxWrapper.h | 20 ++-- .../src/ports/portWindowsWrapper.h | 6 +- src/common/data_provider/src/sharedDefs.h | 1 - src/common/data_provider/src/sysInfoLinux.cpp | 10 +- src/common/data_provider/src/sysInfoMac.cpp | 2 +- src/common/data_provider/src/sysInfoUnix.cpp | 2 +- src/common/data_provider/src/sysInfoWin.cpp | 20 ++-- .../sysInfoPackageLinuxParserRPM_test.cpp | 20 ++-- .../sysInfoPackagesLinuxHelper_test.cpp | 16 +-- .../sysInfoPackagesMAC/pkgWrapper_test.cpp | 100 +++++++++--------- src/modules/inventory/src/inventoryImp.cpp | 27 +++-- .../tests/inventoryImp/inventoryImp_test.cpp | 10 +- 25 files changed, 222 insertions(+), 214 deletions(-) diff --git a/src/common/data_provider/src/network/networkBSDWrapper.h b/src/common/data_provider/src/network/networkBSDWrapper.h index d54d0debbc..f84fbf48ad 100644 --- a/src/common/data_provider/src/network/networkBSDWrapper.h +++ b/src/common/data_provider/src/network/networkBSDWrapper.h @@ -60,7 +60,7 @@ class NetworkBSDInterface final : public INetworkInterfaceWrapper void adapter(nlohmann::json& network) const override { - network["adapter"] = UNKNOWN_VALUE; + network["adapter"] = EMPTY_VALUE; } int family() const override @@ -118,7 +118,7 @@ class NetworkBSDInterface final : public INetworkInterfaceWrapper void gateway(nlohmann::json& network) const override { - network["gateway"] = UNKNOWN_VALUE; + network["gateway"] = EMPTY_VALUE; size_t tableSize { 0 }; int mib[] = { CTL_NET, AF_ROUTE, 0, AF_UNSPEC, NET_RT_FLAGS, RTF_UP | RTF_GATEWAY }; @@ -158,22 +158,22 @@ class NetworkBSDInterface final : public INetworkInterfaceWrapper void metrics(nlohmann::json& network) const override { - network["metric"] = UNKNOWN_VALUE; + network["metric"] = EMPTY_VALUE; } void metricsV6(nlohmann::json& network) const override { - network["metric"] = UNKNOWN_VALUE; + network["metric"] = EMPTY_VALUE; } void dhcp(nlohmann::json& network) const override { - network["dhcp"] = UNKNOWN_VALUE; + network["dhcp"] = EMPTY_VALUE; } void mtu(nlohmann::json& network) const override { - network["mtu"] = UNKNOWN_VALUE; + network["mtu"] = EMPTY_VALUE; if(m_interfaceAddress->ifa_data) { network["mtu"] = reinterpret_cast(m_interfaceAddress->ifa_data)->ifi_mtu; @@ -201,7 +201,7 @@ class NetworkBSDInterface final : public INetworkInterfaceWrapper void type(nlohmann::json& network) const override { - network["type"] = UNKNOWN_VALUE; + network["type"] = EMPTY_VALUE; if (m_interfaceAddress->ifa_addr) { @@ -221,7 +221,7 @@ class NetworkBSDInterface final : public INetworkInterfaceWrapper void MAC(nlohmann::json& network) const override { - network["mac"] = UNKNOWN_VALUE; + network["mac"] = EMPTY_VALUE; auto sdl { reinterpret_cast(m_interfaceAddress->ifa_addr) }; std::stringstream ss; diff --git a/src/common/data_provider/src/network/networkLinuxWrapper.h b/src/common/data_provider/src/network/networkLinuxWrapper.h index cdf25d5a0c..1e8c5fa7cf 100644 --- a/src/common/data_provider/src/network/networkLinuxWrapper.h +++ b/src/common/data_provider/src/network/networkLinuxWrapper.h @@ -301,7 +301,7 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper void adapter(nlohmann::json& network) const override { - network["adapter"] = UNKNOWN_VALUE; + network["adapter"] = EMPTY_VALUE; } int family() const override @@ -321,7 +321,7 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper void broadcast(nlohmann::json& network) const override { - network["broadcast"] = UNKNOWN_VALUE; + network["broadcast"] = EMPTY_VALUE; if (m_interfaceAddress->ifa_ifu.ifu_broadaddr) { @@ -357,7 +357,7 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper { m_interfaceAddress->ifa_ifu.ifu_broadaddr ? network["broadcast"] = getNameInfo(m_interfaceAddress->ifa_ifu.ifu_broadaddr, sizeof(struct sockaddr_in6)) : - network["broadcast"] = UNKNOWN_VALUE; + network["broadcast"] = EMPTY_VALUE; } void gateway(nlohmann::json& network) const override @@ -372,13 +372,13 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper void metricsV6(nlohmann::json& network) const override { - network["metric"] = UNKNOWN_VALUE; + network["metric"] = EMPTY_VALUE; } void dhcp(nlohmann::json& network) const override { auto fileData { Utils::getFileContent(WM_SYS_IF_FILE) }; - network["dhcp"] = UNKNOWN_VALUE; + network["dhcp"] = EMPTY_VALUE; const auto family { this->family() }; const auto ifName { this->name() }; @@ -449,7 +449,7 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper void mtu(nlohmann::json& network) const override { - network["mtu"] = UNKNOWN_VALUE; + network["mtu"] = EMPTY_VALUE; const auto mtuFileContent { Utils::getFileContent(std::string(WM_SYS_IFDATA_DIR) + this->name() + "/mtu") }; if (!mtuFileContent.empty()) @@ -507,7 +507,7 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper void type(nlohmann::json& network) const override { - network["type"] = UNKNOWN_VALUE; + network["type"] = EMPTY_VALUE; const auto networkTypeCode { Utils::getFileContent(std::string(WM_SYS_IFDATA_DIR) + this->name() + "/type") }; if (!networkTypeCode.empty()) @@ -518,7 +518,7 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper void state(nlohmann::json& network) const override { - network["state"] = UNKNOWN_VALUE; + network["state"] = EMPTY_VALUE; const std::string operationalState { Utils::getFileContent(std::string(WM_SYS_IFDATA_DIR) + this->name() + "/operstate") }; if (!operationalState.empty()) @@ -529,7 +529,7 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper void MAC(nlohmann::json& network) const override { - network["mac"] = UNKNOWN_VALUE; + network["mac"] = EMPTY_VALUE; const std::string macContent { Utils::getFileContent(std::string(WM_SYS_IFDATA_DIR) + this->name() + "/address")}; if (!macContent.empty()) diff --git a/src/common/data_provider/src/network/networkWindowsWrapper.h b/src/common/data_provider/src/network/networkWindowsWrapper.h index 8487816d66..973cba4588 100644 --- a/src/common/data_provider/src/network/networkWindowsWrapper.h +++ b/src/common/data_provider/src/network/networkWindowsWrapper.h @@ -164,7 +164,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void broadcast(nlohmann::json& network) const override { - network["broadcast"] = UNKNOWN_VALUE; + network["broadcast"] = EMPTY_VALUE; const auto address { this->address() }; const auto netmask { this->netmask() }; @@ -180,7 +180,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void broadcastV6(nlohmann::json& network) const override { - network["broadcast"] = UNKNOWN_VALUE; + network["broadcast"] = EMPTY_VALUE; } void gateway(nlohmann::json& network) const override @@ -246,7 +246,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper if (retVal.empty()) { - network["gateway"] = UNKNOWN_VALUE; + network["gateway"] = EMPTY_VALUE; } else { @@ -258,7 +258,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void metrics(nlohmann::json& network) const override { - network["metric"] = UNKNOWN_VALUE; + network["metric"] = EMPTY_VALUE; if (Utils::isVistaOrLater()) { @@ -268,7 +268,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void metricsV6(nlohmann::json& network) const override { - network["metric"] = UNKNOWN_VALUE; + network["metric"] = EMPTY_VALUE; if (Utils::isVistaOrLater()) { @@ -278,7 +278,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void dhcp(nlohmann::json& network) const override { - network["dhcp"] = UNKNOWN_VALUE; + network["dhcp"] = EMPTY_VALUE; const auto family { this->adapterFamily() }; if (AF_INET == family) @@ -312,7 +312,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void type(nlohmann::json& network) const override { - network["type"] = UNKNOWN_VALUE; + network["type"] = EMPTY_VALUE; const auto interfaceType { NETWORK_INTERFACE_TYPES.find(m_interfaceAddress->IfType) }; if (NETWORK_INTERFACE_TYPES.end() != interfaceType) @@ -323,7 +323,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void state(nlohmann::json& network) const override { - network["state"] = UNKNOWN_VALUE; + network["state"] = EMPTY_VALUE; const auto opStatus { NETWORK_OPERATIONAL_STATUS.find(m_interfaceAddress->OperStatus) }; if (NETWORK_OPERATIONAL_STATUS.end() != opStatus) @@ -334,7 +334,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void MAC(nlohmann::json& network) const override { - network["mac"] = UNKNOWN_VALUE; + network["mac"] = EMPTY_VALUE; constexpr auto MAC_ADDRESS_LENGTH { 6 }; if (MAC_ADDRESS_LENGTH == m_interfaceAddress->PhysicalAddressLength) diff --git a/src/common/data_provider/src/packages/appxWindowsWrapper.h b/src/common/data_provider/src/packages/appxWindowsWrapper.h index 2e48a88c31..c7da0206b0 100644 --- a/src/common/data_provider/src/packages/appxWindowsWrapper.h +++ b/src/common/data_provider/src/packages/appxWindowsWrapper.h @@ -57,12 +57,12 @@ class AppxWindowsWrapper final : public IPackageWrapper void groups(nlohmann::json& package) const override { - package["groups"] = UNKNOWN_VALUE; + package["groups"] = EMPTY_VALUE; } void description(nlohmann::json& package) const override { - package["description"] = UNKNOWN_VALUE; + package["description"] = EMPTY_VALUE; } void architecture(nlohmann::json& package) const override @@ -77,12 +77,12 @@ class AppxWindowsWrapper final : public IPackageWrapper void osPatch(nlohmann::json& package) const override { - package["os_patch"] = UNKNOWN_VALUE; + package["os_patch"] = EMPTY_VALUE; } void source(nlohmann::json& package) const override { - package["source"] = UNKNOWN_VALUE; + package["source"] = EMPTY_VALUE; } void location(nlohmann::json& package) const override @@ -92,7 +92,7 @@ class AppxWindowsWrapper final : public IPackageWrapper void priority(nlohmann::json& package) const override { - package["priority"] = UNKNOWN_VALUE; + package["priority"] = EMPTY_VALUE; } void size(nlohmann::json& package) const override diff --git a/src/common/data_provider/src/packages/brewWrapper.h b/src/common/data_provider/src/packages/brewWrapper.h index 98ae3a4aad..2e01c0d783 100644 --- a/src/common/data_provider/src/packages/brewWrapper.h +++ b/src/common/data_provider/src/packages/brewWrapper.h @@ -76,7 +76,7 @@ class BrewWrapper final : public IPackageWrapper void groups(nlohmann::json& package) const override { - package["groups"] = UNKNOWN_VALUE; + package["groups"] = EMPTY_VALUE; } void description(nlohmann::json& package) const override @@ -86,7 +86,7 @@ class BrewWrapper final : public IPackageWrapper void architecture(nlohmann::json& package) const override { - package["architecture"] = UNKNOWN_VALUE; + package["architecture"] = EMPTY_VALUE; } void format(nlohmann::json& package) const override @@ -96,7 +96,7 @@ class BrewWrapper final : public IPackageWrapper void osPatch(nlohmann::json& package) const override { - package["os_patch"] = UNKNOWN_VALUE; + package["os_patch"] = EMPTY_VALUE; } void source(nlohmann::json& package) const override @@ -111,27 +111,27 @@ class BrewWrapper final : public IPackageWrapper void vendor(nlohmann::json& package) const override { - package["vendor"] = UNKNOWN_VALUE; + package["vendor"] = EMPTY_VALUE; } void priority(nlohmann::json& package) const override { - package["priority"] = UNKNOWN_VALUE; + package["priority"] = EMPTY_VALUE; } void size(nlohmann::json& package) const override { - package["size"] = UNKNOWN_VALUE; + package["size"] = EMPTY_VALUE; } void install_time(nlohmann::json& package) const override { - package["install_time"] = UNKNOWN_VALUE; + package["install_time"] = EMPTY_VALUE; } void multiarch(nlohmann::json& package) const override { - package["multiarch"] = UNKNOWN_VALUE; + package["multiarch"] = EMPTY_VALUE; } private: diff --git a/src/common/data_provider/src/packages/macportsWrapper.h b/src/common/data_provider/src/packages/macportsWrapper.h index e849a340ff..5cb931a13c 100644 --- a/src/common/data_provider/src/packages/macportsWrapper.h +++ b/src/common/data_provider/src/packages/macportsWrapper.h @@ -58,11 +58,11 @@ class MacportsWrapper final : public IPackageWrapper } void groups(nlohmann::json& package) const override { - package["groups"] = UNKNOWN_VALUE; + package["groups"] = EMPTY_VALUE; } void description(nlohmann::json& package) const override { - package["description"] = UNKNOWN_VALUE; + package["description"] = EMPTY_VALUE; } void architecture(nlohmann::json& package) const override { @@ -74,11 +74,11 @@ class MacportsWrapper final : public IPackageWrapper } void osPatch(nlohmann::json& package) const override { - package["os_patch"] = UNKNOWN_VALUE; + package["os_patch"] = EMPTY_VALUE; } void source(nlohmann::json& package) const override { - package["source"] = UNKNOWN_VALUE; + package["source"] = EMPTY_VALUE; } void location(nlohmann::json& package) const override { @@ -86,17 +86,17 @@ class MacportsWrapper final : public IPackageWrapper } void vendor(nlohmann::json& package) const override { - package["vendor"] = UNKNOWN_VALUE; + package["vendor"] = EMPTY_VALUE; } void priority(nlohmann::json& package) const override { - package["priority"] = UNKNOWN_VALUE; + package["priority"] = EMPTY_VALUE; } void size(nlohmann::json& package) const override { - package["size"] = UNKNOWN_VALUE; + package["size"] = EMPTY_VALUE; } void install_time(nlohmann::json& package) const override @@ -106,7 +106,7 @@ class MacportsWrapper final : public IPackageWrapper void multiarch(nlohmann::json& package) const override { - package["multiarch"] = UNKNOWN_VALUE; + package["multiarch"] = EMPTY_VALUE; } private: void getPkgData(SQLiteLegacy::IStatement& stmt) diff --git a/src/common/data_provider/src/packages/packageLinuxParserHelper.h b/src/common/data_provider/src/packages/packageLinuxParserHelper.h index 9dd7ea0b14..c83b0baa96 100644 --- a/src/common/data_provider/src/packages/packageLinuxParserHelper.h +++ b/src/common/data_provider/src/packages/packageLinuxParserHelper.h @@ -69,15 +69,15 @@ namespace PackageLinuxHelper { ret["name"] = info.at("Package"); - nlohmann::json priority {UNKNOWN_VALUE}; - nlohmann::json groups {UNKNOWN_VALUE}; + nlohmann::json priority {EMPTY_VALUE}; + nlohmann::json groups {EMPTY_VALUE}; // The multiarch field won't have a default value nlohmann::json multiarch; - nlohmann::json architecture {UNKNOWN_VALUE}; - nlohmann::json source {UNKNOWN_VALUE}; - nlohmann::json version {UNKNOWN_VALUE}; - nlohmann::json vendor {UNKNOWN_VALUE}; - nlohmann::json description {UNKNOWN_VALUE}; + nlohmann::json architecture {EMPTY_VALUE}; + nlohmann::json source {EMPTY_VALUE}; + nlohmann::json version {EMPTY_VALUE}; + nlohmann::json vendor {EMPTY_VALUE}; + nlohmann::json description {EMPTY_VALUE}; int size { 0 }; auto it{info.find("Priority")}; @@ -151,9 +151,9 @@ namespace PackageLinuxHelper ret["source"] = source; ret["version"] = version; ret["format"] = "deb"; - ret["location"] = UNKNOWN_VALUE; + ret["location"] = EMPTY_VALUE; ret["vendor"] = vendor; - ret["install_time"] = UNKNOWN_VALUE; + ret["install_time"] = EMPTY_VALUE; ret["description"] = description; } @@ -166,9 +166,9 @@ namespace PackageLinuxHelper std::string name; std::string version; - nlohmann::json vendor { UNKNOWN_VALUE }; - nlohmann::json install_time { UNKNOWN_VALUE }; - nlohmann::json description { UNKNOWN_VALUE }; + nlohmann::json vendor { EMPTY_VALUE }; + nlohmann::json install_time { EMPTY_VALUE }; + nlohmann::json description { EMPTY_VALUE }; int size { 0 }; bool hasName { false }; bool hasVersion { false }; @@ -260,10 +260,10 @@ namespace PackageLinuxHelper ret["source"] = "snapcraft"; ret["format"] = "snap"; - ret["priority"] = UNKNOWN_VALUE; - ret["multiarch"] = UNKNOWN_VALUE; - ret["architecture"] = UNKNOWN_VALUE; - ret["groups"] = UNKNOWN_VALUE; + ret["priority"] = EMPTY_VALUE; + ret["multiarch"] = EMPTY_VALUE; + ret["architecture"] = EMPTY_VALUE; + ret["groups"] = EMPTY_VALUE; return ret; } diff --git a/src/common/data_provider/src/packages/packageLinuxRpmParserHelper.h b/src/common/data_provider/src/packages/packageLinuxRpmParserHelper.h index 98fa355d10..e1e88ff92a 100644 --- a/src/common/data_provider/src/packages/packageLinuxRpmParserHelper.h +++ b/src/common/data_provider/src/packages/packageLinuxRpmParserHelper.h @@ -48,14 +48,14 @@ namespace PackageLinuxHelper ret["name"] = package.name; ret["size"] = package.size; ret["install_time"] = package.installTime; - ret["location"] = UNKNOWN_VALUE; + ret["location"] = EMPTY_VALUE; ret["groups"] = package.group; ret["version"] = version; - ret["priority"] = UNKNOWN_VALUE; + ret["priority"] = EMPTY_VALUE; ret["architecture"] = package.architecture; - ret["source"] = UNKNOWN_VALUE; + ret["source"] = EMPTY_VALUE; ret["format"] = "rpm"; - ret["vendor"] = package.vendor.empty() ? UNKNOWN_VALUE : package.vendor; + ret["vendor"] = package.vendor.empty() ? EMPTY_VALUE : package.vendor; ret["description"] = package.description; // The multiarch field won't have a default value } diff --git a/src/common/data_provider/src/packages/packageLinuxRpmParserHelperLegacy.h b/src/common/data_provider/src/packages/packageLinuxRpmParserHelperLegacy.h index 520f6e0b4d..f457256f17 100644 --- a/src/common/data_provider/src/packages/packageLinuxRpmParserHelperLegacy.h +++ b/src/common/data_provider/src/packages/packageLinuxRpmParserHelperLegacy.h @@ -64,16 +64,16 @@ namespace PackageLinuxHelper ret["name"] = name; ret["size"] = size.empty() || size.compare(DEFAULT_VALUE) == 0 ? 0 : stoi(size); - ret["install_time"] = install_time.empty() || install_time.compare(DEFAULT_VALUE) == 0 ? UNKNOWN_VALUE : nlohmann::json(install_time); - ret["location"] = UNKNOWN_VALUE; - ret["groups"] = groups.empty() || groups.compare(DEFAULT_VALUE) == 0 ? UNKNOWN_VALUE : nlohmann::json(groups); - ret["version"] = version.empty() || version.compare(DEFAULT_VALUE) == 0 ? UNKNOWN_VALUE : nlohmann::json(version); - ret["priority"] = UNKNOWN_VALUE; - ret["architecture"] = architecture.empty() || architecture.compare(DEFAULT_VALUE) == 0 ? UNKNOWN_VALUE : nlohmann::json(architecture); - ret["source"] = UNKNOWN_VALUE; + ret["install_time"] = install_time.empty() || install_time.compare(DEFAULT_VALUE) == 0 ? EMPTY_VALUE : nlohmann::json(install_time); + ret["location"] = EMPTY_VALUE; + ret["groups"] = groups.empty() || groups.compare(DEFAULT_VALUE) == 0 ? EMPTY_VALUE : nlohmann::json(groups); + ret["version"] = version.empty() || version.compare(DEFAULT_VALUE) == 0 ? EMPTY_VALUE : nlohmann::json(version); + ret["priority"] = EMPTY_VALUE; + ret["architecture"] = architecture.empty() || architecture.compare(DEFAULT_VALUE) == 0 ? EMPTY_VALUE : nlohmann::json(architecture); + ret["source"] = EMPTY_VALUE; ret["format"] = "rpm"; - ret["vendor"] = vendor.empty() || vendor.compare(DEFAULT_VALUE) == 0 ? UNKNOWN_VALUE : nlohmann::json(vendor); - ret["description"] = description.empty() || description.compare(DEFAULT_VALUE) == 0 ? UNKNOWN_VALUE : nlohmann::json(description); + ret["vendor"] = vendor.empty() || vendor.compare(DEFAULT_VALUE) == 0 ? EMPTY_VALUE : nlohmann::json(vendor); + ret["description"] = description.empty() || description.compare(DEFAULT_VALUE) == 0 ? EMPTY_VALUE : nlohmann::json(description); // The multiarch field won't have a default value } } diff --git a/src/common/data_provider/src/packages/packagesNPM.hpp b/src/common/data_provider/src/packages/packagesNPM.hpp index 271445e9ca..a408a04ee2 100644 --- a/src/common/data_provider/src/packages/packagesNPM.hpp +++ b/src/common/data_provider/src/packages/packagesNPM.hpp @@ -47,16 +47,16 @@ class NPM final const auto packageJson = TJsonReader::readJson(path); nlohmann::json packageInfo; - packageInfo["groups"] = UNKNOWN_VALUE; - packageInfo["description"] = UNKNOWN_VALUE; - packageInfo["architecture"] = UNKNOWN_VALUE; + packageInfo["groups"] = EMPTY_VALUE; + packageInfo["description"] = EMPTY_VALUE; + packageInfo["architecture"] = EMPTY_VALUE; packageInfo["format"] = "npm"; - packageInfo["source"] = UNKNOWN_VALUE; + packageInfo["source"] = EMPTY_VALUE; packageInfo["location"] = path.string(); - packageInfo["priority"] = UNKNOWN_VALUE; - packageInfo["size"] = UNKNOWN_VALUE; - packageInfo["vendor"] = UNKNOWN_VALUE; - packageInfo["install_time"] = UNKNOWN_VALUE; + packageInfo["priority"] = EMPTY_VALUE; + packageInfo["size"] = EMPTY_VALUE; + packageInfo["vendor"] = EMPTY_VALUE; + packageInfo["install_time"] = EMPTY_VALUE; // The multiarch field won't have a default value // Iterate over fields diff --git a/src/common/data_provider/src/packages/packagesPYPI.hpp b/src/common/data_provider/src/packages/packagesPYPI.hpp index 5bb6ee6023..cc0ab6c266 100644 --- a/src/common/data_provider/src/packages/packagesPYPI.hpp +++ b/src/common/data_provider/src/packages/packagesPYPI.hpp @@ -38,16 +38,16 @@ class PYPI final : public TFileSystem, public TFileIO // Parse the METADATA file nlohmann::json packageInfo; - packageInfo["groups"] = UNKNOWN_VALUE; - packageInfo["description"] = UNKNOWN_VALUE; - packageInfo["architecture"] = UNKNOWN_VALUE; + packageInfo["groups"] = EMPTY_VALUE; + packageInfo["description"] = EMPTY_VALUE; + packageInfo["architecture"] = EMPTY_VALUE; packageInfo["format"] = "pypi"; - packageInfo["source"] = UNKNOWN_VALUE; + packageInfo["source"] = EMPTY_VALUE; packageInfo["location"] = path.string(); - packageInfo["priority"] = UNKNOWN_VALUE; - packageInfo["size"] = UNKNOWN_VALUE; - packageInfo["vendor"] = UNKNOWN_VALUE; - packageInfo["install_time"] = UNKNOWN_VALUE; + packageInfo["priority"] = EMPTY_VALUE; + packageInfo["size"] = EMPTY_VALUE; + packageInfo["vendor"] = EMPTY_VALUE; + packageInfo["install_time"] = EMPTY_VALUE; // The multiarch field won't have a default value TFileIO::readLineByLine(path, diff --git a/src/common/data_provider/src/packages/pkgWrapper.h b/src/common/data_provider/src/packages/pkgWrapper.h index 51e2151117..442dfd44b3 100644 --- a/src/common/data_provider/src/packages/pkgWrapper.h +++ b/src/common/data_provider/src/packages/pkgWrapper.h @@ -72,7 +72,7 @@ class PKGWrapper final : public IPackageWrapper } void architecture(nlohmann::json& package) const override { - package["architecture"] = UNKNOWN_VALUE; + package["architecture"] = EMPTY_VALUE; } void format(nlohmann::json& package) const override { @@ -80,7 +80,7 @@ class PKGWrapper final : public IPackageWrapper } void osPatch(nlohmann::json& package) const override { - package["os_patch"] = UNKNOWN_VALUE; + package["os_patch"] = EMPTY_VALUE; } void source(nlohmann::json& package) const override { @@ -97,12 +97,12 @@ class PKGWrapper final : public IPackageWrapper void priority(nlohmann::json& package) const override { - package["priority"] = UNKNOWN_VALUE; + package["priority"] = EMPTY_VALUE; } void size(nlohmann::json& package) const override { - package["size"] = UNKNOWN_VALUE; + package["size"] = EMPTY_VALUE; } void install_time(nlohmann::json& package) const override @@ -112,7 +112,7 @@ class PKGWrapper final : public IPackageWrapper void multiarch(nlohmann::json& package) const override { - package["multiarch"] = UNKNOWN_VALUE; + package["multiarch"] = EMPTY_VALUE; } private: diff --git a/src/common/data_provider/src/ports/portBSDWrapper.h b/src/common/data_provider/src/ports/portBSDWrapper.h index 49e571f955..cf258fce16 100644 --- a/src/common/data_provider/src/ports/portBSDWrapper.h +++ b/src/common/data_provider/src/ports/portBSDWrapper.h @@ -69,7 +69,7 @@ class BSDPortWrapper final : public IPortWrapper void protocol(nlohmann::json& port) const override { - port["protocol"] = UNKNOWN_VALUE; + port["protocol"] = EMPTY_VALUE; const auto it { PORTS_TYPE.find(m_spSocketInfo->psi.soi_kind) }; if (it != PORTS_TYPE.end()) @@ -135,12 +135,12 @@ class BSDPortWrapper final : public IPortWrapper void txQueue(nlohmann::json& port) const override { - port["tx_queue"] = UNKNOWN_VALUE; + port["tx_queue"] = EMPTY_VALUE; } void rxQueue(nlohmann::json& port) const override { - port["rx_queue"] = UNKNOWN_VALUE; + port["rx_queue"] = EMPTY_VALUE; } void inode(nlohmann::json& port) const override @@ -150,7 +150,7 @@ class BSDPortWrapper final : public IPortWrapper void state(nlohmann::json& port) const override { - port["state"] = UNKNOWN_VALUE; + port["state"] = EMPTY_VALUE; const auto itProtocol { PORTS_TYPE.find(m_spSocketInfo->psi.soi_kind) }; diff --git a/src/common/data_provider/src/ports/portLinuxWrapper.h b/src/common/data_provider/src/ports/portLinuxWrapper.h index e035c4e678..2c8301842b 100644 --- a/src/common/data_provider/src/ports/portLinuxWrapper.h +++ b/src/common/data_provider/src/ports/portLinuxWrapper.h @@ -135,13 +135,13 @@ class LinuxPortWrapper final : public IPortWrapper } else { - port["protocol"] = UNKNOWN_VALUE; + port["protocol"] = EMPTY_VALUE; } } void localIp(nlohmann::json& port) const override { - port["local_ip"] = UNKNOWN_VALUE; + port["local_ip"] = EMPTY_VALUE; if (m_localAddresses.size() == AddressField::ADDRESS_FIELD_SIZE) { @@ -169,13 +169,13 @@ class LinuxPortWrapper final : public IPortWrapper } else { - port["local_port"] = UNKNOWN_VALUE; + port["local_port"] = EMPTY_VALUE; } } void remoteIP(nlohmann::json& port) const override { - port["remote_ip"] = UNKNOWN_VALUE; + port["remote_ip"] = EMPTY_VALUE; if (m_remoteAddresses.size() == AddressField::ADDRESS_FIELD_SIZE) { @@ -203,7 +203,7 @@ class LinuxPortWrapper final : public IPortWrapper } else { - port["remote_port"] = UNKNOWN_VALUE; + port["remote_port"] = EMPTY_VALUE; } } @@ -220,7 +220,7 @@ class LinuxPortWrapper final : public IPortWrapper } else { - port["tx_queue"] = UNKNOWN_VALUE; + port["tx_queue"] = EMPTY_VALUE; } } @@ -237,7 +237,7 @@ class LinuxPortWrapper final : public IPortWrapper } else { - port["rx_queue"] = UNKNOWN_VALUE; + port["rx_queue"] = EMPTY_VALUE; } } @@ -258,7 +258,7 @@ class LinuxPortWrapper final : public IPortWrapper void state(nlohmann::json& port) const override { - port["state"] = UNKNOWN_VALUE; + port["state"] = EMPTY_VALUE; const auto it { PROTOCOL_TYPE.find(m_type) }; if (PROTOCOL_TYPE.end() != it && TCP == it->second) @@ -279,12 +279,12 @@ class LinuxPortWrapper final : public IPortWrapper void processName(nlohmann::json& port) const override { - port["process"] = UNKNOWN_VALUE; + port["process"] = EMPTY_VALUE; } void pid(nlohmann::json& port) const override { - port["pid"] = UNKNOWN_VALUE; + port["pid"] = EMPTY_VALUE; } }; diff --git a/src/common/data_provider/src/ports/portWindowsWrapper.h b/src/common/data_provider/src/ports/portWindowsWrapper.h index a332967707..63a69438b4 100644 --- a/src/common/data_provider/src/ports/portWindowsWrapper.h +++ b/src/common/data_provider/src/ports/portWindowsWrapper.h @@ -161,12 +161,12 @@ class WindowsPortWrapper final : public IPortWrapper void txQueue(nlohmann::json& port) const override { - port["tx_queue"] = UNKNOWN_VALUE; + port["tx_queue"] = EMPTY_VALUE; } void rxQueue(nlohmann::json& port) const override { - port["rx_queue"] = UNKNOWN_VALUE; + port["rx_queue"] = EMPTY_VALUE; } void inode(nlohmann::json& port) const override @@ -176,7 +176,7 @@ class WindowsPortWrapper final : public IPortWrapper void state(nlohmann::json& port) const override { - port["state"] = UNKNOWN_VALUE; + port["state"] = EMPTY_VALUE; const auto itState { STATE_TYPE.find(m_state) }; if (STATE_TYPE.end() != itState) diff --git a/src/common/data_provider/src/sharedDefs.h b/src/common/data_provider/src/sharedDefs.h index 515224298d..8829193cb1 100644 --- a/src/common/data_provider/src/sharedDefs.h +++ b/src/common/data_provider/src/sharedDefs.h @@ -33,7 +33,6 @@ constexpr auto RPM_PATH {"/var/lib/rpm/"}; constexpr auto SNAP_PATH {"/var/lib/snapd"}; -constexpr auto UNKNOWN_VALUE {nullptr}; constexpr auto EMPTY_VALUE {""}; constexpr auto MAC_ADDRESS_COUNT_SEGMENTS { diff --git a/src/common/data_provider/src/sysInfoLinux.cpp b/src/common/data_provider/src/sysInfoLinux.cpp index 5f469fef79..effdfc83e0 100644 --- a/src/common/data_provider/src/sysInfoLinux.cpp +++ b/src/common/data_provider/src/sysInfoLinux.cpp @@ -139,7 +139,7 @@ static nlohmann::json getProcessInfo(const SysInfoProcess& process) static void getSerialNumber(nlohmann::json& info) { - info["board_serial"] = UNKNOWN_VALUE; + info["board_serial"] = EMPTY_VALUE; std::fstream file{WM_SYS_HW_DIR, std::ios_base::in}; if (file.is_open()) @@ -152,7 +152,7 @@ static void getSerialNumber(nlohmann::json& info) static void getCpuName(nlohmann::json& info) { - info["cpu_name"] = UNKNOWN_VALUE; + info["cpu_name"] = EMPTY_VALUE; std::map systemInfo; getSystemInfo(WM_SYS_CPU_DIR, ":", systemInfo); const auto& it { systemInfo.find("model name") }; @@ -165,7 +165,7 @@ static void getCpuName(nlohmann::json& info) static void getCpuCores(nlohmann::json& info) { - info["cpu_cores"] = UNKNOWN_VALUE; + info["cpu_cores"] = EMPTY_VALUE; std::map systemInfo; getSystemInfo(WM_SYS_CPU_DIR, ":", systemInfo); const auto& it { systemInfo.find("processor") }; @@ -178,7 +178,7 @@ static void getCpuCores(nlohmann::json& info) static void getCpuMHz(nlohmann::json& info) { - info["cpu_mhz"] = UNKNOWN_VALUE; + info["cpu_mhz"] = EMPTY_VALUE; int retVal { 0 }; std::map systemInfo; getSystemInfo(WM_SYS_CPU_DIR, ":", systemInfo); @@ -347,7 +347,7 @@ nlohmann::json SysInfo::getOsInfo() const { ret["os_name"] = "Linux"; ret["os_platform"] = "linux"; - ret["os_version"] = UNKNOWN_VALUE; + ret["os_version"] = EMPTY_VALUE; } if (uname(&uts) >= 0) diff --git a/src/common/data_provider/src/sysInfoMac.cpp b/src/common/data_provider/src/sysInfoMac.cpp index a404dd0bed..dc5a82b735 100644 --- a/src/common/data_provider/src/sysInfoMac.cpp +++ b/src/common/data_provider/src/sysInfoMac.cpp @@ -65,7 +65,7 @@ static nlohmann::json getProcessInfo(const ProcessTaskInfo& taskInfo, const pid_ jsProcessInfo["pid"] = std::to_string(pid); jsProcessInfo["name"] = taskInfo.pbsd.pbi_name; - jsProcessInfo["state"] = UNKNOWN_VALUE; + jsProcessInfo["state"] = EMPTY_VALUE; jsProcessInfo["ppid"] = taskInfo.pbsd.pbi_ppid; const auto eUser { getpwuid(taskInfo.pbsd.pbi_uid) }; diff --git a/src/common/data_provider/src/sysInfoUnix.cpp b/src/common/data_provider/src/sysInfoUnix.cpp index 9b81009077..689b7c0ee5 100644 --- a/src/common/data_provider/src/sysInfoUnix.cpp +++ b/src/common/data_provider/src/sysInfoUnix.cpp @@ -20,7 +20,7 @@ static void getOsInfoFromUname(nlohmann::json& info) { info["os_name"] = "Unix"; info["os_platform"] = "Unix"; - info["os_version"] = UNKNOWN_VALUE; + info["os_version"] = EMPTY_VALUE; } diff --git a/src/common/data_provider/src/sysInfoWin.cpp b/src/common/data_provider/src/sysInfoWin.cpp index 653edb1bb9..fec4af5620 100644 --- a/src/common/data_provider/src/sysInfoWin.cpp +++ b/src/common/data_provider/src/sysInfoWin.cpp @@ -370,13 +370,13 @@ static void getPackagesFromReg(const HKEY key, const std::string& subKey, std::f { packageJson["name"] = value; - packageJson["version"] = UNKNOWN_VALUE; + packageJson["version"] = EMPTY_VALUE; if (packageReg.string("DisplayVersion", value)) { packageJson["version"] = value; } - packageJson["vendor"] = UNKNOWN_VALUE; + packageJson["vendor"] = EMPTY_VALUE; if (packageReg.string("Publisher", value)) { packageJson["vendor"] = value; @@ -399,13 +399,13 @@ static void getPackagesFromReg(const HKEY key, const std::string& subKey, std::f packageJson["install_time"] = Utils::timestampToISO8601(packageReg.keyModificationDate()); } - packageJson["location"] = UNKNOWN_VALUE; + packageJson["location"] = EMPTY_VALUE; if (packageReg.string("InstallLocation", value)) { packageJson["location"] = value; } - packageJson["architecture"] = UNKNOWN_VALUE; + packageJson["architecture"] = EMPTY_VALUE; if (access & KEY_WOW64_32KEY) { packageJson["architecture"] = "i686"; @@ -415,11 +415,11 @@ static void getPackagesFromReg(const HKEY key, const std::string& subKey, std::f packageJson["architecture"] = "x86_64"; } - packageJson["description"] = UNKNOWN_VALUE; - packageJson["groups"] = UNKNOWN_VALUE; - packageJson["priority"] = UNKNOWN_VALUE; - packageJson["size"] = UNKNOWN_VALUE; - packageJson["source"] = UNKNOWN_VALUE; + packageJson["description"] = EMPTY_VALUE; + packageJson["groups"] = EMPTY_VALUE; + packageJson["priority"] = EMPTY_VALUE; + packageJson["size"] = EMPTY_VALUE; + packageJson["source"] = EMPTY_VALUE; packageJson["format"] = "win"; returnCallback(packageJson); @@ -509,7 +509,7 @@ static std::string getSerialNumber() } else { - ret = UNKNOWN_VALUE; + ret = EMPTY_VALUE; } } diff --git a/src/common/data_provider/tests/sysInfoPackageLinuxParserRpm/sysInfoPackageLinuxParserRPM_test.cpp b/src/common/data_provider/tests/sysInfoPackageLinuxParserRpm/sysInfoPackageLinuxParserRPM_test.cpp index 14efe36def..a75df6442e 100644 --- a/src/common/data_provider/tests/sysInfoPackageLinuxParserRpm/sysInfoPackageLinuxParserRPM_test.cpp +++ b/src/common/data_provider/tests/sysInfoPackageLinuxParserRpm/sysInfoPackageLinuxParserRPM_test.cpp @@ -187,7 +187,7 @@ TEST(SysInfoPackageLinuxParserRPM_test, rpmFromBerkleyDB) CallbackMock wrapper; auto expectedPackage1 = - R"({"architecture":"amd64","description":"The Open Source Security Platform","format":"rpm","groups":"test","install_time":"5","name":"Wazuh","size":321,"vendor":"The Wazuh Team","version":"123:4.4-1","location":null,"priority":null,"source":null})"_json; + R"({"architecture":"amd64","description":"The Open Source Security Platform","format":"rpm","groups":"test","install_time":"5","name":"Wazuh","size":321,"vendor":"The Wazuh Team","version":"123:4.4-1","location":"","priority":"","source":""})"_json; auto utils_mock { std::make_unique() }; auto libdb_mock { std::make_unique() }; @@ -345,7 +345,7 @@ TEST(SysInfoPackageLinuxParserRPM_test, rpmFromLibRPM) CallbackMock wrapper; auto expectedPackage1 = - R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":null,"priority":null,"source":null})"_json; + R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":"","source":""})"_json; auto utils_mock { std::make_unique() }; auto rpm_mock { std::make_unique() }; @@ -402,9 +402,9 @@ TEST(SysInfoPackageLinuxParserRPM_test, rpmFallbackFromLibRPM) CallbackMock wrapper; auto expectedPackage1 = - R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":null,"priority":null,"source":null})"_json; + R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":"","source":""})"_json; auto expectedPackage2 = - R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":null,"priority":null,"source":null})"_json; + R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":"","priority":"","source":""})"_json; auto utils_mock { std::make_unique() }; auto rpm_mock { std::make_unique() }; @@ -430,9 +430,9 @@ TEST(SysInfoPackageLinuxParserRPM_test, rpmFallbackFromBerkleyDBConfigError) CallbackMock wrapper; auto expectedPackage1 = - R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":null,"priority":null,"source":null})"_json; + R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":"","source":""})"_json; auto expectedPackage2 = - R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":null,"priority":null,"source":null})"_json; + R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":"","priority":"","source":""})"_json; auto utils_mock { std::make_unique() }; auto libdb_mock { std::make_unique() }; @@ -459,9 +459,9 @@ TEST(SysInfoPackageLinuxParserRPM_test, rpmFallbackFromBerkleyDBOpenError) CallbackMock wrapper; auto expectedPackage1 = - R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":null,"priority":null,"source":null})"_json; + R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":"","source":""})"_json; auto expectedPackage2 = - R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":null,"priority":null,"source":null})"_json; + R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":"","priority":"","source":""})"_json; auto utils_mock { std::make_unique() }; auto libdb_mock { std::make_unique() }; @@ -497,9 +497,9 @@ TEST(SysInfoPackageLinuxParserRPM_test, rpmFallbackFromBerkleyDBCursorError) CallbackMock wrapper; auto expectedPackage1 = - R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":null,"priority":null,"source":null})"_json; + R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":"","source":""})"_json; auto expectedPackage2 = - R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":null,"priority":null,"source":null})"_json; + R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":"","priority":"","source":""})"_json; auto utils_mock { std::make_unique() }; auto libdb_mock { std::make_unique() }; diff --git a/src/common/data_provider/tests/sysInfoPackagesLinuxHelper/sysInfoPackagesLinuxHelper_test.cpp b/src/common/data_provider/tests/sysInfoPackagesLinuxHelper/sysInfoPackagesLinuxHelper_test.cpp index 816d230959..f7a0f1e3cc 100644 --- a/src/common/data_provider/tests/sysInfoPackagesLinuxHelper/sysInfoPackagesLinuxHelper_test.cpp +++ b/src/common/data_provider/tests/sysInfoPackagesLinuxHelper/sysInfoPackagesLinuxHelper_test.cpp @@ -99,13 +99,13 @@ TEST_F(SysInfoPackagesLinuxHelperTest, parseRpmInformationUnknownInEmpty) EXPECT_FALSE(jsPackageInfo.empty()); EXPECT_EQ("curl", jsPackageInfo["name"]); EXPECT_EQ(0, jsPackageInfo["size"]); - EXPECT_EQ(UNKNOWN_VALUE, jsPackageInfo["install_time"]); - EXPECT_EQ(UNKNOWN_VALUE, jsPackageInfo["groups"]); - EXPECT_EQ(UNKNOWN_VALUE, jsPackageInfo["version"]); - EXPECT_EQ(UNKNOWN_VALUE, jsPackageInfo["architecture"]); + EXPECT_EQ(EMPTY_VALUE, jsPackageInfo["install_time"]); + EXPECT_EQ(EMPTY_VALUE, jsPackageInfo["groups"]); + EXPECT_EQ(EMPTY_VALUE, jsPackageInfo["version"]); + EXPECT_EQ(EMPTY_VALUE, jsPackageInfo["architecture"]); EXPECT_EQ("rpm", jsPackageInfo["format"]); - EXPECT_EQ(UNKNOWN_VALUE, jsPackageInfo["vendor"]); - EXPECT_EQ(UNKNOWN_VALUE, jsPackageInfo["description"]); + EXPECT_EQ(EMPTY_VALUE, jsPackageInfo["vendor"]); + EXPECT_EQ(EMPTY_VALUE, jsPackageInfo["description"]); } @@ -370,9 +370,9 @@ TEST_F(SysInfoPackagesLinuxHelperTest, parseSnapCorrectMapping) EXPECT_EQ("gnome-3-38-2004", jsPackageInfo["name"]); EXPECT_EQ(363151360, jsPackageInfo["size"]); EXPECT_EQ("2022/11/23 20:33:59", jsPackageInfo["install_time"]); - EXPECT_TRUE(jsPackageInfo["groups"].is_null()); + EXPECT_EQ("", jsPackageInfo["groups"]); EXPECT_EQ("0+git.6f39565", jsPackageInfo["version"]); - EXPECT_TRUE(jsPackageInfo["groups"].is_null()); + EXPECT_EQ("", jsPackageInfo["groups"]); EXPECT_EQ("snap", jsPackageInfo["format"]); EXPECT_EQ("Canonical", jsPackageInfo["vendor"]); EXPECT_EQ("Shared GNOME 3.38 Ubuntu stack", jsPackageInfo["description"]); diff --git a/src/common/data_provider/tests/sysInfoPackagesMAC/pkgWrapper_test.cpp b/src/common/data_provider/tests/sysInfoPackagesMAC/pkgWrapper_test.cpp index 5255851827..984dd264f1 100644 --- a/src/common/data_provider/tests/sysInfoPackagesMAC/pkgWrapper_test.cpp +++ b/src/common/data_provider/tests/sysInfoPackagesMAC/pkgWrapper_test.cpp @@ -45,11 +45,11 @@ TEST_F(PKGWrapperTest, LongVersion) wrapper->description(packageJson); EXPECT_EQ(packageJson["description"], "com.operasoftware.Opera"); wrapper->architecture(packageJson); - EXPECT_EQ(packageJson["architecture"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["architecture"], EMPTY_VALUE); wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -57,13 +57,13 @@ TEST_F(PKGWrapperTest, LongVersion) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "operasoftware"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["size"], EMPTY_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); } TEST_F(PKGWrapperTest, ShortVersion) @@ -89,11 +89,11 @@ TEST_F(PKGWrapperTest, ShortVersion) wrapper->description(packageJson); EXPECT_EQ(packageJson["description"], "com.operasoftware.Opera"); wrapper->architecture(packageJson); - EXPECT_EQ(packageJson["architecture"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["architecture"], EMPTY_VALUE); wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -101,13 +101,13 @@ TEST_F(PKGWrapperTest, ShortVersion) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "operasoftware"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["size"], EMPTY_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); } TEST_F(PKGWrapperTest, NoName) @@ -133,11 +133,11 @@ TEST_F(PKGWrapperTest, NoName) wrapper->description(packageJson); EXPECT_EQ(packageJson["description"], "com.operasoftware.Opera"); wrapper->architecture(packageJson); - EXPECT_EQ(packageJson["architecture"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["architecture"], EMPTY_VALUE); wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -145,13 +145,13 @@ TEST_F(PKGWrapperTest, NoName) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "operasoftware"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["size"], EMPTY_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); } TEST_F(PKGWrapperTest, NoVersion) @@ -177,11 +177,11 @@ TEST_F(PKGWrapperTest, NoVersion) wrapper->description(packageJson); EXPECT_EQ(packageJson["description"], "com.operasoftware.Opera"); wrapper->architecture(packageJson); - EXPECT_EQ(packageJson["architecture"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["architecture"], EMPTY_VALUE); wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -189,13 +189,13 @@ TEST_F(PKGWrapperTest, NoVersion) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "operasoftware"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["size"], EMPTY_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); } TEST_F(PKGWrapperTest, NoGroups) @@ -221,11 +221,11 @@ TEST_F(PKGWrapperTest, NoGroups) wrapper->description(packageJson); EXPECT_EQ(packageJson["description"], "com.operasoftware.Opera"); wrapper->architecture(packageJson); - EXPECT_EQ(packageJson["architecture"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["architecture"], EMPTY_VALUE); wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -233,13 +233,13 @@ TEST_F(PKGWrapperTest, NoGroups) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "operasoftware"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["size"], EMPTY_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); } TEST_F(PKGWrapperTest, NoDescription) @@ -265,11 +265,11 @@ TEST_F(PKGWrapperTest, NoDescription) wrapper->description(packageJson); EXPECT_EQ(packageJson["description"], EMPTY_VALUE); wrapper->architecture(packageJson); - EXPECT_EQ(packageJson["architecture"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["architecture"], EMPTY_VALUE); wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -277,13 +277,13 @@ TEST_F(PKGWrapperTest, NoDescription) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], EMPTY_VALUE); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["size"], EMPTY_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); } TEST_F(PKGWrapperTest, NoVendor) @@ -309,11 +309,11 @@ TEST_F(PKGWrapperTest, NoVendor) wrapper->description(packageJson); EXPECT_EQ(packageJson["description"], "description_text"); wrapper->architecture(packageJson); - EXPECT_EQ(packageJson["architecture"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["architecture"], EMPTY_VALUE); wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -321,13 +321,13 @@ TEST_F(PKGWrapperTest, NoVendor) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], EMPTY_VALUE); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["size"], EMPTY_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); } TEST_F(PKGWrapperTest, pkgVersionXML) @@ -353,11 +353,11 @@ TEST_F(PKGWrapperTest, pkgVersionXML) wrapper->description(packageJson); EXPECT_EQ(packageJson["description"], "com.wazuh.pkg.wazuh-agent"); wrapper->architecture(packageJson); - EXPECT_EQ(packageJson["architecture"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["architecture"], EMPTY_VALUE); wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "receipts"); wrapper->location(packageJson); @@ -365,13 +365,13 @@ TEST_F(PKGWrapperTest, pkgVersionXML) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "wazuh"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["size"], EMPTY_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], "2024-11-07T08:58:38Z"); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); } TEST_F(PKGWrapperTest, pkgVersionBin) @@ -397,11 +397,11 @@ TEST_F(PKGWrapperTest, pkgVersionBin) wrapper->description(packageJson); EXPECT_EQ(packageJson["description"], "us.zoom.pkg.videomeeting"); wrapper->architecture(packageJson); - EXPECT_EQ(packageJson["architecture"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["architecture"], EMPTY_VALUE); wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "receipts"); wrapper->location(packageJson); @@ -409,13 +409,13 @@ TEST_F(PKGWrapperTest, pkgVersionBin) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "zoom"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["size"], EMPTY_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], "2024-11-08T11:44:04Z"); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); } TEST_F(PKGWrapperTest, pkgVersionLong) @@ -441,11 +441,11 @@ TEST_F(PKGWrapperTest, pkgVersionLong) wrapper->description(packageJson); EXPECT_EQ(packageJson["description"], "org.R-project.x86_64.R.GUI.pkg"); wrapper->architecture(packageJson); - EXPECT_EQ(packageJson["architecture"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["architecture"], EMPTY_VALUE); wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "receipts"); wrapper->location(packageJson); @@ -453,11 +453,11 @@ TEST_F(PKGWrapperTest, pkgVersionLong) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "R-project"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["size"], EMPTY_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], "2024-11-13T10:59:10Z"); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); + EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); } diff --git a/src/modules/inventory/src/inventoryImp.cpp b/src/modules/inventory/src/inventoryImp.cpp index 3aaf968be5..89bcc673a8 100644 --- a/src/modules/inventory/src/inventoryImp.cpp +++ b/src/modules/inventory/src/inventoryImp.cpp @@ -560,7 +560,7 @@ nlohmann::json Inventory::EcsHardwareData(const nlohmann::json& originalData, bo auto setField = [&](const std::string& keyPath, const std::string& jsonKey, const std::optional& defaultValue) { if (createFields || originalData.contains(jsonKey)) { nlohmann::json::json_pointer pointer(keyPath); - if (originalData.contains(jsonKey) && !originalData[jsonKey].is_null()) { + if (originalData.contains(jsonKey) && originalData[jsonKey] != EMPTY_VALUE) { ret[pointer] = originalData[jsonKey]; } else if (defaultValue.has_value()) { ret[pointer] = *defaultValue; @@ -588,7 +588,7 @@ nlohmann::json Inventory::EcsSystemData(const nlohmann::json& originalData, bool auto setField = [&](const std::string& keyPath, const std::string& jsonKey, const std::optional& defaultValue) { if (createFields || originalData.contains(jsonKey)) { nlohmann::json::json_pointer pointer(keyPath); - if (originalData.contains(jsonKey) && !originalData[jsonKey].is_null()) { + if (originalData.contains(jsonKey) && originalData[jsonKey] != EMPTY_VALUE) { ret[pointer] = originalData[jsonKey]; } else if (defaultValue.has_value()) { ret[pointer] = *defaultValue; @@ -617,7 +617,7 @@ nlohmann::json Inventory::EcsPackageData(const nlohmann::json& originalData, boo auto setField = [&](const std::string& keyPath, const std::string& jsonKey, const std::optional& defaultValue) { if (createFields || originalData.contains(jsonKey)) { nlohmann::json::json_pointer pointer(keyPath); - if (originalData.contains(jsonKey) && !originalData[jsonKey].is_null()) { + if (originalData.contains(jsonKey) && originalData[jsonKey] != EMPTY_VALUE) { ret[pointer] = originalData[jsonKey]; } else if (defaultValue.has_value()) { ret[pointer] = *defaultValue; @@ -646,7 +646,7 @@ nlohmann::json Inventory::EcsProcessesData(const nlohmann::json& originalData, b auto setField = [&](const std::string& keyPath, const std::string& jsonKey, const std::optional& defaultValue) { if (createFields || originalData.contains(jsonKey)) { nlohmann::json::json_pointer pointer(keyPath); - if (originalData.contains(jsonKey) && !originalData[jsonKey].is_null()) { + if (originalData.contains(jsonKey) && originalData[jsonKey] != EMPTY_VALUE) { ret[pointer] = originalData[jsonKey]; } else if (defaultValue.has_value()) { ret[pointer] = *defaultValue; @@ -680,8 +680,14 @@ nlohmann::json Inventory::EcsHotfixesData(const nlohmann::json& originalData, bo if(createFields || originalData.contains("hotfix")) { - ret["package"]["hotfix"]["name"] = (originalData.contains("hotfix") && !originalData["hotfix"].is_null()) ? - originalData["hotfix"] : EMPTY_VALUE; + if(originalData.contains("hotfix") && originalData["hotfix"] != EMPTY_VALUE) + { + ret["package"]["hotfix"]["name"] = originalData["hotfix"]; + } + else + { + ret["package"]["hotfix"]["name"] = EMPTY_VALUE; + } } return ret; @@ -694,7 +700,7 @@ nlohmann::json Inventory::EcsPortData(const nlohmann::json& originalData, bool c auto setField = [&](const std::string& keyPath, const std::string& jsonKey, const std::optional& defaultValue) { if (createFields || originalData.contains(jsonKey)) { nlohmann::json::json_pointer pointer(keyPath); - if (originalData.contains(jsonKey) && !originalData[jsonKey].is_null()) { + if (originalData.contains(jsonKey) && originalData[jsonKey] != EMPTY_VALUE) { ret[pointer] = originalData[jsonKey]; } else if (defaultValue.has_value()) { ret[pointer] = *defaultValue; @@ -742,7 +748,7 @@ nlohmann::json Inventory::EcsNetworkData(const nlohmann::json& originalData, boo auto setField = [&](const std::string& keyPath, const std::string& jsonKey, const std::optional& defaultValue) { if (createFields || originalData.contains(jsonKey)) { nlohmann::json::json_pointer pointer(keyPath); - if (originalData.contains(jsonKey) && !originalData[jsonKey].is_null()) { + if (originalData.contains(jsonKey) && originalData[jsonKey] != EMPTY_VALUE) { ret[pointer] = originalData[jsonKey]; } else if (defaultValue.has_value()) { ret[pointer] = *defaultValue; @@ -788,7 +794,10 @@ nlohmann::json Inventory::EcsNetworkData(const nlohmann::json& originalData, boo setField("/network/type", "proto_type", EMPTY_VALUE); setField("/network/metric", "metric", std::nullopt); /* TODO this field should include http or https, it's related to an application not to a interface */ - ret["network"]["protocol"] = UNKNOWN_VALUE; + if (createFields) + { + ret["network"]["protocol"] = nullptr; + } setField("/observer/ingress/interface/alias", "adapter", EMPTY_VALUE); setField("/observer/ingress/interface/name", "iface", EMPTY_VALUE); diff --git a/src/modules/inventory/tests/inventoryImp/inventoryImp_test.cpp b/src/modules/inventory/tests/inventoryImp/inventoryImp_test.cpp index e38032221c..aab24038d7 100644 --- a/src/modules/inventory/tests/inventoryImp/inventoryImp_test.cpp +++ b/src/modules/inventory/tests/inventoryImp/inventoryImp_test.cpp @@ -870,7 +870,7 @@ TEST_F(InventoryImpTest, noPortsAll) }; const auto expectedResult6 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":""},"network":{"protocol":"udp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"operation":"create","type":"ports"})" }; const auto expectedResult7 { @@ -1287,12 +1287,12 @@ TEST_F(InventoryImpTest, portAllEnable) }; const auto expectedResult1 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":43481},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":""},"network":{"protocol":"udp"},"process":{"name":null,"pid":0},"source":{"ip":["0.0.0.0"],"port":47748}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":43481},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp"},"process":{"name":null,"pid":0},"source":{"ip":["0.0.0.0"],"port":47748}},"operation":"create","type":"ports"})" }; const auto expectedResult2 { - R"({"data":{"destination":{"ip":["::"],"port":0},"file":{"inode":43482},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":""},"network":{"protocol":"udp6"},"process":{"name":null,"pid":0},"source":{"ip":["::"],"port":51087}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["::"],"port":0},"file":{"inode":43482},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp6"},"process":{"name":null,"pid":0},"source":{"ip":["::"],"port":51087}},"operation":"create","type":"ports"})" }; const auto expectedResult3 @@ -1435,12 +1435,12 @@ TEST_F(InventoryImpTest, portAllDisable) }; const auto expectedResult1 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":43481},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":""},"network":{"protocol":"udp"},"process":{"name":null,"pid":0},"source":{"ip":["0.0.0.0"],"port":47748}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":43481},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp"},"process":{"name":null,"pid":0},"source":{"ip":["0.0.0.0"],"port":47748}},"operation":"create","type":"ports"})" }; const auto expectedResult2 { - R"({"data":{"destination":{"ip":["::"],"port":0},"file":{"inode":43482},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":""},"network":{"protocol":"udp6"},"process":{"name":null,"pid":0},"source":{"ip":["::"],"port":51087}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["::"],"port":0},"file":{"inode":43482},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp6"},"process":{"name":null,"pid":0},"source":{"ip":["::"],"port":51087}},"operation":"create","type":"ports"})" }; const auto expectedResult3 From 2443997fa89c3a29498e78845f3e53de9884bd85 Mon Sep 17 00:00:00 2001 From: nbertoldo Date: Wed, 15 Jan 2025 19:46:45 -0300 Subject: [PATCH 06/10] feat: refactor first scan metadata cleanup --- src/modules/inventory/include/inventory.hpp | 12 ++ src/modules/inventory/src/inventory.cpp | 13 +- src/modules/inventory/src/inventoryImp.cpp | 161 ++++++++++++++------ 3 files changed, 136 insertions(+), 50 deletions(-) diff --git a/src/modules/inventory/include/inventory.hpp b/src/modules/inventory/include/inventory.hpp index d37104821b..b2ee4e99f5 100644 --- a/src/modules/inventory/include/inventory.hpp +++ b/src/modules/inventory/include/inventory.hpp @@ -85,6 +85,11 @@ class Inventory { std::string GetPrimaryKeys(const nlohmann::json& data, const std::string& table); std::string CalculateHashId(const nlohmann::json& data, const std::string& table); + void WriteMetadata(const std::string &key, const std::string &value); + std::string ReadMetadata(const std::string &key); + void DeleteMetadata(const std::string &key); + void CleanMetadata(); + const std::string m_moduleName {"inventory"}; std::string m_agentUUID {""}; // Agent UUID std::shared_ptr m_spInfo; @@ -109,4 +114,11 @@ class Inventory { std::unique_ptr m_spNormalizer; std::string m_scanTime; std::function m_pushMessage; + bool m_hardwareFirstScan; // Hardware first scan flag + bool m_systemFirstScan; // System first scan flag + bool m_networksFirstScan; // Networks first scan flag + bool m_packagesFirstScan; // Installed packages first scan flag + bool m_portsFirstScan; // Opened ports first scan flag + bool m_processesFirstScan; // Running processes first scan flag + bool m_hotfixesFirstScan; // Windows hotfixes installed first scan flag }; diff --git a/src/modules/inventory/src/inventory.cpp b/src/modules/inventory/src/inventory.cpp index dac77c1c48..41ef0d0a5d 100644 --- a/src/modules/inventory/src/inventory.cpp +++ b/src/modules/inventory/src/inventory.cpp @@ -11,13 +11,14 @@ void Inventory::Start() { if (!m_enabled) { LogInfo("Inventory module is disabled."); + CleanMetadata(); return; } - if(m_enabled){ - LogInfo("Inventory module started."); - ShowConfig(); - } + LogInfo("Inventory module started."); + + ShowConfig(); + DBSync::initialize(LogErrorInventory); try @@ -33,9 +34,7 @@ void Inventory::Start() { LogErrorInventory(ex.what()); } - if(m_enabled){ - LogInfo("Inventory module stopped."); - } + LogInfo("Inventory module stopped."); } void Inventory::Setup(std::shared_ptr configurationParser) { diff --git a/src/modules/inventory/src/inventoryImp.cpp b/src/modules/inventory/src/inventoryImp.cpp index 89bcc673a8..d466e66ba4 100644 --- a/src/modules/inventory/src/inventoryImp.cpp +++ b/src/modules/inventory/src/inventoryImp.cpp @@ -183,7 +183,17 @@ constexpr auto PORTS_TABLE { "ports" }; constexpr auto PROCESSES_TABLE { "processes" }; constexpr auto OS_TABLE { "system" }; constexpr auto HW_TABLE { "hardware" }; - +constexpr auto MD_TABLE { "metadata" }; + +const std::unordered_map TABLE_TO_KEY_MAP = { + {NETWORKS_TABLE, "networks-first-scan"}, + {PACKAGES_TABLE, "packages-first-scan"}, + {HOTFIXES_TABLE, "hotfixes-first-scan"}, + {PORTS_TABLE, "ports-first-scan"}, + {PROCESSES_TABLE, "processes-first-scan"}, + {OS_TABLE, "system-first-scan"}, + {HW_TABLE, "hardware-first-scan"} +}; static std::string GetItemId(const nlohmann::json& item, const std::vector& idFields) { @@ -443,6 +453,13 @@ Inventory::Inventory() , m_hotfixes { true } , m_stopping { true } , m_notify { true } + , m_hardwareFirstScan { true } + , m_systemFirstScan { true } + , m_networksFirstScan { true } + , m_packagesFirstScan { true } + , m_portsFirstScan { true } + , m_processesFirstScan { true } + , m_hotfixesFirstScan { true } {} std::string Inventory::GetCreateStatement() const @@ -480,70 +497,57 @@ void Inventory::Init(const std::shared_ptr& spInfo, m_spNormalizer = std::make_unique(normalizerConfigPath, normalizerType); } - m_hardwareFirstScan = ReadMetadata(hardwareFirstScanKey ).empty()? false:true; - m_systemFirstScan = ReadMetadata(systemFirstScanKey ).empty()? false:true; - m_networksFirstScan = ReadMetadata(networksFirstScanKey ).empty()? false:true; - m_packagesFirstScan = ReadMetadata(packagesFirstScanKey ).empty()? false:true; - m_portsFirstScan = ReadMetadata(portsFirstScanKey ).empty()? false:true; - m_portsAllFirstScan = ReadMetadata(portsAllFirstScanKey ).empty()? false:true; - m_processesFirstScan = ReadMetadata(processesFirstScanKey).empty()? false:true; - m_hotfixesFirstScan = ReadMetadata(hotfixesFirstScanKey ).empty()? false:true; + m_hardwareFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(HW_TABLE)).empty() ? false:true; + m_systemFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(OS_TABLE)).empty() ? false:true; + m_networksFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(NETWORKS_TABLE)).empty() ? false:true; + m_packagesFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(PACKAGES_TABLE)).empty() ? false:true; + m_portsFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(PORTS_TABLE)).empty() ? false:true; + m_processesFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(PROCESSES_TABLE)).empty() ? false:true; + m_hotfixesFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(HOTFIXES_TABLE)).empty() ? false:true; - if(m_hardwareFirstScan && (!m_hardware || !m_enabled)) + if(m_hardwareFirstScan && !m_hardware) { - DeleteMetadata(hardwareFirstScanKey); + DeleteMetadata(TABLE_TO_KEY_MAP.at(HW_TABLE)); m_hardwareFirstScan = false; } - if(m_systemFirstScan && (!m_system || !m_enabled)) + if(m_systemFirstScan && !m_system) { - DeleteMetadata(systemFirstScanKey); + DeleteMetadata(TABLE_TO_KEY_MAP.at(OS_TABLE)); m_systemFirstScan = false; } - if(m_networksFirstScan && (!m_networks || !m_enabled)) + if(m_networksFirstScan && !m_networks) { - DeleteMetadata(networksFirstScanKey); + DeleteMetadata(TABLE_TO_KEY_MAP.at(NETWORKS_TABLE)); m_networksFirstScan = false; - } - if(m_packagesFirstScan && (!m_packages || !m_enabled)) + if(m_packagesFirstScan && !m_packages) { - DeleteMetadata(packagesFirstScanKey); + DeleteMetadata(TABLE_TO_KEY_MAP.at(PACKAGES_TABLE)); m_packagesFirstScan = false; } - if(m_portsFirstScan && (!m_ports || !m_enabled)) + if(m_portsFirstScan && !m_ports) { - DeleteMetadata(portsFirstScanKey); + DeleteMetadata(TABLE_TO_KEY_MAP.at(PORTS_TABLE)); m_portsFirstScan = false; } - if(m_portsAllFirstScan && (!m_portsAll || !m_enabled)) - { - DeleteMetadata(portsAllFirstScanKey); - m_portsAllFirstScan = false; - } - if(m_processesFirstScan && (!m_processes || !m_enabled)) + if(m_processesFirstScan && !m_processes) { - DeleteMetadata(processesFirstScanKey); + DeleteMetadata(TABLE_TO_KEY_MAP.at(PROCESSES_TABLE)); m_processesFirstScan = false; } - if(m_hotfixesFirstScan && (!m_hotfixes || !m_enabled)) + if(m_hotfixesFirstScan && !m_hotfixes) { - DeleteMetadata(hotfixesFirstScanKey); + DeleteMetadata(TABLE_TO_KEY_MAP.at(HOTFIXES_TABLE)); m_hotfixesFirstScan = false; } - if(m_enabled) - SyncLoop(); - else{ - Destroy(); - std::unique_lock lock{m_mutex}; - m_spDBSync.reset(nullptr); - } + SyncLoop(); } void Inventory::Destroy() @@ -821,7 +825,7 @@ void Inventory::ScanHardware() LogTrace( "Ending hardware scan"); if(!m_hardwareFirstScan){ - WriteMetadata(hardwareFirstScanKey, Utils::getCurrentISO8601()); + WriteMetadata(TABLE_TO_KEY_MAP.at(HW_TABLE), Utils::getCurrentISO8601()); m_hardwareFirstScan = true; } } @@ -844,7 +848,7 @@ void Inventory::ScanOs() LogTrace( "Ending os scan"); if(!m_systemFirstScan){ - WriteMetadata(systemFirstScanKey, Utils::getCurrentISO8601()); + WriteMetadata(TABLE_TO_KEY_MAP.at(OS_TABLE), Utils::getCurrentISO8601()); m_systemFirstScan = true; } } @@ -947,7 +951,7 @@ void Inventory::ScanNetwork() } if(!m_networksFirstScan){ - WriteMetadata(networksFirstScanKey, Utils::getCurrentISO8601()); + WriteMetadata(TABLE_TO_KEY_MAP.at(NETWORKS_TABLE), Utils::getCurrentISO8601()); m_networksFirstScan = true; } @@ -995,7 +999,7 @@ void Inventory::ScanPackages() txn.getDeletedRows(callback); if(!m_packagesFirstScan){ - WriteMetadata(packagesFirstScanKey, Utils::getCurrentISO8601()); + WriteMetadata(TABLE_TO_KEY_MAP.at(PACKAGES_TABLE), Utils::getCurrentISO8601()); m_packagesFirstScan = true; } @@ -1016,7 +1020,7 @@ void Inventory::ScanHotfixes() } if(!m_hotfixesFirstScan){ - WriteMetadata(hotfixesFirstScanKey, Utils::getCurrentISO8601()); + WriteMetadata(TABLE_TO_KEY_MAP.at(HOTFIXES_TABLE), Utils::getCurrentISO8601()); m_hotfixesFirstScan = true; } @@ -1094,7 +1098,7 @@ void Inventory::ScanPorts() LogTrace( "Ending ports scan"); if(!m_portsFirstScan){ - WriteMetadata(portsFirstScanKey, Utils::getCurrentISO8601()); + WriteMetadata(TABLE_TO_KEY_MAP.at(PORTS_TABLE), Utils::getCurrentISO8601()); m_portsFirstScan = true; } } @@ -1134,7 +1138,7 @@ void Inventory::ScanProcesses() txn.getDeletedRows(callback); if(!m_processesFirstScan){ - WriteMetadata(processesFirstScanKey, Utils::getCurrentISO8601()); + WriteMetadata(TABLE_TO_KEY_MAP.at(PROCESSES_TABLE), Utils::getCurrentISO8601()); m_processesFirstScan = true; } @@ -1180,3 +1184,74 @@ void Inventory::SyncLoop() std::unique_lock lock{m_mutex}; m_spDBSync.reset(nullptr); } + +void Inventory::WriteMetadata(const std::string &key, const std::string &value){ + auto insertQuery + { + InsertQuery::builder() + .table(MD_TABLE) + .data({{"key", key}, {"value", value}}) + .build() + }; + m_spDBSync->insertData(insertQuery.query()); +} + +std::string Inventory::ReadMetadata(const std::string &key) { + std::string result; + std::string filter = "WHERE key = '" + key + "'"; + auto selectQuery = SelectQuery::builder() + .table("metadata") + .columnList({"key", "value"}) + .rowFilter(filter) + .build(); + + auto callback = [&result](ReturnTypeCallback returnTypeCallback, const nlohmann::json& resultData) { + (void)returnTypeCallback; + if (resultData.is_object() && resultData.contains("key") && resultData.contains("value")) { + result = resultData["value"]; + } + }; + + m_spDBSync->selectRows(selectQuery.query(), callback); + + return result; +} + +void Inventory::DeleteMetadata(const std::string &key){ + auto deleteQuery + { + DeleteQuery::builder() + .table("metadata") + .data({{"key", key}}) + .rowFilter("") + .build() + }; + m_spDBSync->deleteRows(deleteQuery.query()); +} + +void Inventory::CleanMetadata() +{ + DBSync::initialize(LogErrorInventory); + + try + { + { + std::unique_lock lock{m_mutex}; + m_spDBSync = std::make_unique(HostType::AGENT, + DbEngineType::SQLITE3, + m_dbFilePath, + METADATA_SQL_STATEMENT, + DbManagement::PERSISTENT); + for (const auto& key : TABLE_TO_KEY_MAP) { + if(!ReadMetadata(key.second).empty()){ + DeleteMetadata(key.second); + } + } + m_spDBSync.reset(); + } + } + catch (const std::exception& ex) + { + LogErrorInventory(ex.what()); + } +} From 0c066143517b4bca6e21095f0b5d3c99b8416199 Mon Sep 17 00:00:00 2001 From: cborla Date: Thu, 16 Jan 2025 01:59:16 -0300 Subject: [PATCH 07/10] feat: adaptat senddeltaevent and inventory to include satateless message --- src/agent/src/message_queue_utils.cpp | 3 +- src/modules/inventory/include/inventory.hpp | 9 +- src/modules/inventory/src/inventory.cpp | 36 +- src/modules/inventory/src/inventoryImp.cpp | 386 ++++++++++++++---- .../tests/inventory/inventory_test.cpp | 127 ++++-- .../tests/inventoryImp/inventoryImp_test.cpp | 238 +++++++---- 6 files changed, 583 insertions(+), 216 deletions(-) diff --git a/src/agent/src/message_queue_utils.cpp b/src/agent/src/message_queue_utils.cpp index 59972a3a3d..273b4fc3e2 100644 --- a/src/agent/src/message_queue_utils.cpp +++ b/src/agent/src/message_queue_utils.cpp @@ -19,7 +19,8 @@ GetMessagesFromQueue(std::shared_ptr multiTypeQueue, const auto messages = co_await multiTypeQueue->getNextBytesAwaitable(messageType, messagesSize, "", ""); for (const auto& message : messages) { - output += "\n" + message.metaData + (message.data.dump() == "{}" ? "" : "\n" + message.data.dump()); + output += (message.metaData.empty() ? "" : "\n" + message.metaData) + + (message.data.dump() == "{}" ? "" : "\n" + message.data.dump()); } co_return std::tuple {static_cast(messages.size()), output}; diff --git a/src/modules/inventory/include/inventory.hpp b/src/modules/inventory/include/inventory.hpp index b2ee4e99f5..1a665edd67 100644 --- a/src/modules/inventory/include/inventory.hpp +++ b/src/modules/inventory/include/inventory.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -61,16 +62,14 @@ class Inventory { nlohmann::json EcsPackageData(const nlohmann::json& originalData, bool createFields = true); nlohmann::json EcsPortData(const nlohmann::json& originalData, bool createFields = true); nlohmann::json EcsNetworkData(const nlohmann::json& originalData, bool createFields = true); - nlohmann::json GetOSData(); - nlohmann::json GetHardwareData(); nlohmann::json GetNetworkData(); nlohmann::json GetPortsData(); - void UpdateChanges(const std::string& table, const nlohmann::json& values); + void UpdateChanges(const std::string& table, const nlohmann::json& values, const bool isFirstScan); void NotifyChange(ReturnTypeCallback result, const nlohmann::json& data, const std::string& table); void TryCatchTask(const std::function& task) const; void ScanHardware(); - void ScanOs(); + void ScanSystem(); void ScanNetwork(); void ScanPackages(); void ScanHotfixes(); @@ -84,6 +83,8 @@ class Inventory { nlohmann::json EcsData(const nlohmann::json& data, const std::string& table, bool createFields = true); std::string GetPrimaryKeys(const nlohmann::json& data, const std::string& table); std::string CalculateHashId(const nlohmann::json& data, const std::string& table); + nlohmann::json AddPreviousFields(nlohmann::json& current, const nlohmann::json& previous); + nlohmann::json GenerateStatelessEvent(const std::string& operation, const std::string& type, const nlohmann::json& data); void WriteMetadata(const std::string &key, const std::string &value); std::string ReadMetadata(const std::string &key); diff --git a/src/modules/inventory/src/inventory.cpp b/src/modules/inventory/src/inventory.cpp index 41ef0d0a5d..ba019d8676 100644 --- a/src/modules/inventory/src/inventory.cpp +++ b/src/modules/inventory/src/inventory.cpp @@ -76,20 +76,38 @@ void Inventory::SetPushMessageFunction(const std::function& pushMe void Inventory::SendDeltaEvent(const std::string& data) { const auto jsonData = nlohmann::json::parse(data); - auto metadata = nlohmann::json::object(); - metadata["module"] = Name(); - metadata["type"] = jsonData["type"]; - metadata["operation"] = jsonData["operation"]; - metadata["id"] = jsonData["id"]; - - const Message statefulMessage{ MessageType::STATEFUL, metadata["operation"] == "delete" ? "{}"_json : jsonData["data"], Name(), jsonData["type"], metadata.dump() }; + const Message statefulMessage{ + MessageType::STATEFUL, + jsonData["metadata"]["operation"] == "delete" ? "{}"_json : jsonData["data"], + Name(), + jsonData["metadata"]["type"], + jsonData["metadata"].dump() + }; if(!m_pushMessage(statefulMessage)) { - LogWarn("Stateful event can't be pushed into the message queue: {}", data); + LogWarn("Stateful event can't be pushed into the message queue: {}", jsonData["data"].dump()); } else { - LogTrace("Stateful event queued: {}, metadata {}", data, metadata.dump()); + LogTrace("Stateful event queued: {}, metadata {}", jsonData["data"].dump(), jsonData["metadata"].dump()); + } + + if(jsonData.contains("stateless") && !jsonData["stateless"].empty()) { + + const Message statelessMessage{ + MessageType::STATELESS, + jsonData["stateless"], + Name(), + jsonData["metadata"]["type"], + "" + }; + + if(!m_pushMessage(statelessMessage)) { + LogWarn("Stateless event can't be pushed into the message queue: {}", jsonData["stateless"].dump()); + } + else { + LogTrace("Stateless event queued: {}, metadata {}", jsonData["stateless"].dump(), jsonData["metadata"].dump()); + } } } diff --git a/src/modules/inventory/src/inventoryImp.cpp b/src/modules/inventory/src/inventoryImp.cpp index d466e66ba4..56a852cb9d 100644 --- a/src/modules/inventory/src/inventoryImp.cpp +++ b/src/modules/inventory/src/inventoryImp.cpp @@ -11,6 +11,10 @@ constexpr std::time_t INVENTORY_DEFAULT_INTERVAL { 3600000 }; constexpr size_t MAX_ID_SIZE = 512; +constexpr int BYTES_IN_KILOBYTE = 1024; +constexpr int KILOBYTES_IN_MEGABYTE = 1024; +constexpr int BYTES_IN_MEGABYTE = BYTES_IN_KILOBYTE * KILOBYTES_IN_MEGABYTE; + constexpr auto QUEUE_SIZE { 4096 @@ -28,7 +32,7 @@ static const std::map OPERATION_MAP // LCOV_EXCL_STOP }; -constexpr auto OS_SQL_STATEMENT +constexpr auto SYSTEM_SQL_STATEMENT { R"(CREATE TABLE system ( hostname TEXT, @@ -49,7 +53,7 @@ constexpr auto OS_SQL_STATEMENT PRIMARY KEY (os_name)) WITHOUT ROWID;)" }; -constexpr auto HW_SQL_STATEMENT +constexpr auto HARDWARE_SQL_STATEMENT { R"(CREATE TABLE hardware ( board_serial TEXT, @@ -181,8 +185,8 @@ constexpr auto PACKAGES_TABLE { "packages" }; constexpr auto HOTFIXES_TABLE { "hotfixes" }; constexpr auto PORTS_TABLE { "ports" }; constexpr auto PROCESSES_TABLE { "processes" }; -constexpr auto OS_TABLE { "system" }; -constexpr auto HW_TABLE { "hardware" }; +constexpr auto SYSTEM_TABLE { "system" }; +constexpr auto HARDWARE_TABLE { "hardware" }; constexpr auto MD_TABLE { "metadata" }; const std::unordered_map TABLE_TO_KEY_MAP = { @@ -191,10 +195,11 @@ const std::unordered_map TABLE_TO_KEY_MAP = { {HOTFIXES_TABLE, "hotfixes-first-scan"}, {PORTS_TABLE, "ports-first-scan"}, {PROCESSES_TABLE, "processes-first-scan"}, - {OS_TABLE, "system-first-scan"}, - {HW_TABLE, "hardware-first-scan"} + {SYSTEM_TABLE, "system-first-scan"}, + {HARDWARE_TABLE, "hardware-first-scan"} }; + static std::string GetItemId(const nlohmann::json& item, const std::vector& idFields) { Utils::HashData hash; @@ -237,11 +242,11 @@ static bool IsElementDuplicated(const nlohmann::json& input, const std::pair().size() <= MAX_ID_SIZE) - { + if (msg["metadata"]["id"].is_string() && msg["metadata"]["id"].get().size() <= MAX_ID_SIZE) { + + nlohmann::json stateless; + stateless = GenerateStatelessEvent(OPERATION_MAP.at(result), table, msg["data"]); + + nlohmann::json eventWithChanges; + eventWithChanges = msg["data"]; + if (!oldData.empty()) + { + stateless["event"]["changed_fields"] = AddPreviousFields(eventWithChanges, oldData); + } + + stateless.update(eventWithChanges); + msg["stateless"] = stateless; msg["data"]["@timestamp"] = m_scanTime; + const auto msgToSend{msg.dump()}; m_reportDiffFunction(msgToSend); } @@ -353,30 +369,41 @@ void Inventory::NotifyChange(ReturnTypeCallback result, const nlohmann::json& da LogWarn("Event discarded for exceeding maximum size allowed in id field."); LogTrace("Event discarded: {}", msg.dump()); } + // LCOV_EXCL_STOP } } else { // LCOV_EXCL_START - nlohmann::json msg; - msg["type"] = table; - msg["operation"] = OPERATION_MAP.at(result); + nlohmann::json msg{ + {"metadata", { + {"type", table}, + {"operation", OPERATION_MAP.at(result)}, + {"module", Name()} + }} + }; - if(result == MODIFIED) - { - msg["data"] = EcsData(data["new"], table); - msg["old_data"] = EcsData(data["old"], table, false); - } - else - { - msg["data"] = EcsData(data, table); - } + msg["data"] = EcsData(result == MODIFIED ? data["new"] : data, table); + nlohmann::json oldData = (result == MODIFIED) ? EcsData(data["old"], table, false) : nlohmann::json{}; - msg["id"] = CalculateHashId(msg["data"], table); + msg["metadata"]["id"] = CalculateHashId(msg["data"], table); - if (msg["id"].is_string() && msg["id"].get().size() <= MAX_ID_SIZE) - { + if (msg["metadata"]["id"].is_string() && msg["metadata"]["id"].get().size() <= MAX_ID_SIZE) { + + nlohmann::json stateless; + stateless = GenerateStatelessEvent(OPERATION_MAP.at(result), table, msg["data"]); + + nlohmann::json eventWithChanges; + eventWithChanges = msg["data"]; + if (!oldData.empty()) + { + stateless["event"]["changed_fields"] = AddPreviousFields(eventWithChanges, oldData); + } + + stateless.update(eventWithChanges); + msg["stateless"] = stateless; msg["data"]["@timestamp"] = m_scanTime; + const auto msgToSend{msg.dump()}; m_reportDiffFunction(msgToSend); } @@ -385,14 +412,14 @@ void Inventory::NotifyChange(ReturnTypeCallback result, const nlohmann::json& da LogWarn("Event discarded for exceeding maximum size allowed in id field."); LogTrace("Event discarded: {}", msg.dump()); } - // LCOV_EXCL_STOP } } } void Inventory::UpdateChanges(const std::string& table, - const nlohmann::json& values) + const nlohmann::json& values, + const bool isFirstScan) { const auto callback { @@ -414,7 +441,10 @@ void Inventory::UpdateChanges(const std::string& table, nlohmann::json input; input["table"] = table; input["data"] = values; - input["options"]["return_old_data"] = true; + if (isFirstScan) + { + input["options"]["return_old_data"] = true; + } txn.syncTxnRow(input); txn.getDeletedRows(callback); } @@ -466,8 +496,8 @@ std::string Inventory::GetCreateStatement() const { std::string ret; - ret += OS_SQL_STATEMENT; - ret += HW_SQL_STATEMENT; + ret += SYSTEM_SQL_STATEMENT; + ret += HARDWARE_SQL_STATEMENT; ret += PACKAGES_SQL_STATEMENT; ret += HOTFIXES_SQL_STATEMENT; ret += PROCESSES_SQL_STATEMENT; @@ -497,8 +527,8 @@ void Inventory::Init(const std::shared_ptr& spInfo, m_spNormalizer = std::make_unique(normalizerConfigPath, normalizerType); } - m_hardwareFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(HW_TABLE)).empty() ? false:true; - m_systemFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(OS_TABLE)).empty() ? false:true; + m_hardwareFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(HARDWARE_TABLE)).empty() ? false:true; + m_systemFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(SYSTEM_TABLE)).empty() ? false:true; m_networksFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(NETWORKS_TABLE)).empty() ? false:true; m_packagesFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(PACKAGES_TABLE)).empty() ? false:true; m_portsFirstScan = ReadMetadata(TABLE_TO_KEY_MAP.at(PORTS_TABLE)).empty() ? false:true; @@ -507,13 +537,13 @@ void Inventory::Init(const std::shared_ptr& spInfo, if(m_hardwareFirstScan && !m_hardware) { - DeleteMetadata(TABLE_TO_KEY_MAP.at(HW_TABLE)); + DeleteMetadata(TABLE_TO_KEY_MAP.at(HARDWARE_TABLE)); m_hardwareFirstScan = false; } if(m_systemFirstScan && !m_system) { - DeleteMetadata(TABLE_TO_KEY_MAP.at(OS_TABLE)); + DeleteMetadata(TABLE_TO_KEY_MAP.at(SYSTEM_TABLE)); m_systemFirstScan = false; } @@ -808,47 +838,35 @@ nlohmann::json Inventory::EcsNetworkData(const nlohmann::json& originalData, boo return ret; } -nlohmann::json Inventory::GetHardwareData() -{ - nlohmann::json ret; - ret[0] = m_spInfo->hardware(); - return ret; -} - void Inventory::ScanHardware() { if (m_hardware) { LogTrace( "Starting hardware scan"); - const auto& hwData{GetHardwareData()}; - UpdateChanges(HW_TABLE, hwData); + nlohmann::json hwData; + hwData[0] = m_spInfo->hardware(); + UpdateChanges(HARDWARE_TABLE, hwData, m_hardwareFirstScan); LogTrace( "Ending hardware scan"); if(!m_hardwareFirstScan){ - WriteMetadata(TABLE_TO_KEY_MAP.at(HW_TABLE), Utils::getCurrentISO8601()); + WriteMetadata(TABLE_TO_KEY_MAP.at(HARDWARE_TABLE), Utils::getCurrentISO8601()); m_hardwareFirstScan = true; } } } -nlohmann::json Inventory::GetOSData() -{ - nlohmann::json ret; - ret[0] = m_spInfo->os(); - return ret; -} - -void Inventory::ScanOs() +void Inventory::ScanSystem() { if (m_system) { LogTrace( "Starting os scan"); - const auto& osData{GetOSData()}; - UpdateChanges(OS_TABLE, osData); + nlohmann::json SystemData; + SystemData[0] = m_spInfo->os(); + UpdateChanges(SYSTEM_TABLE, SystemData, m_systemFirstScan); LogTrace( "Ending os scan"); if(!m_systemFirstScan){ - WriteMetadata(TABLE_TO_KEY_MAP.at(OS_TABLE), Utils::getCurrentISO8601()); + WriteMetadata(TABLE_TO_KEY_MAP.at(SYSTEM_TABLE), Utils::getCurrentISO8601()); m_systemFirstScan = true; } } @@ -946,7 +964,7 @@ void Inventory::ScanNetwork() if (itNet != networkData.end()) { - UpdateChanges(NETWORKS_TABLE, itNet.value()); + UpdateChanges(NETWORKS_TABLE, itNet.value(), m_networksFirstScan); } } @@ -992,7 +1010,10 @@ void Inventory::ScanPackages() if (!rawData.empty()) { input["data"] = nlohmann::json::array( { rawData } ); - input["options"]["return_old_data"] = true; + if (m_packagesFirstScan) + { + input["options"]["return_old_data"] = true; + } txn.syncTxnRow(input); } }); @@ -1016,7 +1037,7 @@ void Inventory::ScanHotfixes() if (!hotfixes.is_null()) { - UpdateChanges(HOTFIXES_TABLE, hotfixes); + UpdateChanges(HOTFIXES_TABLE, hotfixes, m_hotfixesFirstScan); } if(!m_hotfixesFirstScan){ @@ -1094,7 +1115,7 @@ void Inventory::ScanPorts() { LogTrace( "Starting ports scan"); const auto& portsData { GetPortsData() }; - UpdateChanges(PORTS_TABLE, portsData); + UpdateChanges(PORTS_TABLE, portsData, m_portsFirstScan); LogTrace( "Ending ports scan"); if(!m_portsFirstScan){ @@ -1125,16 +1146,20 @@ void Inventory::ScanProcesses() QUEUE_SIZE, callback }; - m_spInfo->processes([&txn](nlohmann::json & rawData) - { - nlohmann::json input; + m_spInfo->processes(std::function( + [this, &txn](nlohmann::json & rawData) + { + nlohmann::json input; + input["table"] = PROCESSES_TABLE; + input["data"] = nlohmann::json::array({ rawData }); - input["table"] = PROCESSES_TABLE; - input["data"] = nlohmann::json::array( { rawData } ); - input["options"]["return_old_data"] = true; + if (m_processesFirstScan) { + input["options"]["return_old_data"] = true; + } - txn.syncTxnRow(input); - }); + txn.syncTxnRow(input); + } + )); txn.getDeletedRows(callback); if(!m_processesFirstScan){ @@ -1152,7 +1177,7 @@ void Inventory::Scan() m_scanTime = Utils::getCurrentISO8601(); TryCatchTask([&]() { ScanHardware(); }); - TryCatchTask([&]() { ScanOs(); }); + TryCatchTask([&]() { ScanSystem(); }); TryCatchTask([&]() { ScanPackages(); }); TryCatchTask([&]() { ScanProcesses(); }); TryCatchTask([&]() { ScanHotfixes(); }); @@ -1200,7 +1225,7 @@ std::string Inventory::ReadMetadata(const std::string &key) { std::string result; std::string filter = "WHERE key = '" + key + "'"; auto selectQuery = SelectQuery::builder() - .table("metadata") + .table(MD_TABLE) .columnList({"key", "value"}) .rowFilter(filter) .build(); @@ -1221,7 +1246,7 @@ void Inventory::DeleteMetadata(const std::string &key){ auto deleteQuery { DeleteQuery::builder() - .table("metadata") + .table(MD_TABLE) .data({{"key", key}}) .rowFilter("") .build() @@ -1255,3 +1280,194 @@ void Inventory::CleanMetadata() LogErrorInventory(ex.what()); } } + +nlohmann::json Inventory::AddPreviousFields(nlohmann::json& current, const nlohmann::json& previous) { + using JsonPair = std::pair; + using PathPair = std::pair; + + std::stack stack; + nlohmann::json modifiedKeys = nlohmann::json::array(); + + stack.emplace("", JsonPair(¤t, &previous)); + + while (!stack.empty()) { + auto [path, pair] = stack.top(); + auto [curr, prev] = pair; + stack.pop(); + + for (auto& [key, value] : prev->items()) { + + std::string currentPath = path; + if (!path.empty()) { + currentPath.append(".").append(key); + } else { + currentPath = key; + } + + if (curr->contains(key)) { + if ((*curr)[key].is_object() && value.is_object()) { + stack.emplace(currentPath, JsonPair(&((*curr)[key]), &value)); + } else if ((*curr)[key] != value) { + modifiedKeys.push_back(currentPath); + (*curr)["previous"][key] = value; + } + } + } + } + return modifiedKeys; +} + +nlohmann::json Inventory::GenerateStatelessEvent(const std::string& operation, const std::string& type, const nlohmann::json& data) { + nlohmann::json event; + std::string action, reason; + std::string created = m_scanTime; + + if (type == "packages") { + std::string packageName = data["package"]["name"]; + std::string version = data["package"]["version"]; + + if (operation == "create") { + action = "package-installed"; + reason = "Package " + packageName + " (version " + version + ") was installed"; + } else if (operation == "update") { + reason = "Package " + packageName + " updated"; + action = "package-updated"; + } else if (operation == "remove") { + action = "package-removed"; + reason = "Package " + packageName + " (version " + version + ") was removed"; + } + + event["event"] = { + {"action", action}, + {"category", {"package"}}, + {"type", {operation == "create" ? "installation" : operation == "update" ? "change" : "deletion"}}, + {"created", created}, + {"reason", reason} + }; + } else if (type == "ports") { + int srcPort = data["source"]["port"]; + int destPort = data["destination"]["port"]; + + if (operation == "create") { + action = "port-detected"; + reason = "New connection established from source port " + std::to_string(srcPort) + " to destination port " + std::to_string(destPort); + } else if (operation == "update") { + action = "port-updated"; + reason = "Change for the connection from source port " + std::to_string(srcPort) + " to destination port " + std::to_string(destPort); + } else if (operation == "remove") { + action = "port-closed"; + reason = "Connection from source port " + std::to_string(srcPort) + " to destination port " + std::to_string(destPort) + " was closed"; + } + + event["event"] = { + {"action", action}, + {"category", {"network"}}, + {"type", {operation == "create" ? "connection" : operation == "update" ? "change" : "end"}}, + {"created", created}, + {"reason", reason} + }; + } else if (type == "hardware") { + std::string cpuName = data["host"]["cpu"]["name"]; + int memoryTotalGB = data["host"]["memory"]["total"].get() / BYTES_IN_MEGABYTE; + std::string serialNumber = data["observer"]["serial_number"]; + + if (operation == "create") { + action = "hardware-detected"; + reason = "New hardware detected: " + cpuName + " with " + std::to_string(memoryTotalGB) + " GB memory"; + } else if (operation == "update") { + action = "hardware-updated"; + reason = "Hardware changed"; + } else if (operation == "remove") { + action = "hardware-removed"; + reason = "Hardware with serial number " + serialNumber + " was removed"; + } + + event["event"] = { + {"action", action}, + {"category", {"host"}}, + {"type", {operation == "create" ? "info" : operation == "update" ? "change" : "deletion"}}, + {"created", created}, + {"reason", reason} + }; + } else if (type == "networks") { + std::string interface = data["observer"]["ingress"]["interface"]["name"]; + + if (operation == "create") { + action = "network-interface-detected"; + reason = "New network interface " + interface + " detected"; + } else if (operation == "update") { + action = "network-interface-updated"; + reason = "Network interface " + interface + "updated"; + } else if (operation == "remove") { + action = "network-interface-removed"; + reason = "Network interface " + interface + " was removed"; + } + + event["event"] = { + {"action", action}, + {"category", {"network"}}, + {"type", {operation == "create" ? "info" : operation == "update" ? "change" : "deletion"}}, + {"created", created}, + {"reason", reason} + }; + } else if (type == "processes") { + std::string processName = data["process"]["name"]; + std::string pid = data["process"]["pid"]; + + if (operation == "create") { + action = "process-started"; + reason = "Process " + processName + " (PID: " + pid + ") was started"; + } else if (operation == "update") { + action = "process-updated"; + reason = "Process " + processName + " (PID: " + pid + ") was updated"; + } else if (operation == "remove") { + action = "process-stopped"; + reason = "Process " + processName + " (PID: " + pid + ") was stopped"; + } + + event["event"] = { + {"action", action}, + {"category", {"process"}}, + {"type", {operation == "create" ? "start" : operation == "update" ? "change" : "end"}}, + {"created", created}, + {"reason", reason} + }; + } else if (type == "system") { + std::string hostname = data["host"]["hostname"]; + std::string osVersion = data["host"]["os"]["version"]; + + action = (operation == "update") ? "system-updated" : "system-detected"; + reason = "System " + hostname + " is running OS version " + osVersion; + + event["event"] = { + {"action", action}, + {"category", {"host"}}, + {"type", {operation == "update" ? "change" : "info"}}, + {"created", created}, + {"reason", reason} + }; + } else if (type == "hotfixes") { + std::string hotfixID = data["package"]["hotfix"]["name"]; + + if (operation == "create") { + action = "hotfix-installed"; + reason = "Hotfix " + hotfixID + " was installed"; + } else if (operation == "update") { + action = "hotfix-updated"; + reason = "Hotfix " + hotfixID + " was updated"; + } else if (operation == "remove") { + action = "hotfix-removed"; + reason = "Hotfix " + hotfixID + " was removed"; + } + + event["event"] = { + {"action", action}, + {"category", {"hotfix"}}, + {"type", {operation == "create" ? "installation" : "deletion"}}, + {"created", created}, + {"reason", reason} + }; + } + + return event; +} diff --git a/src/modules/inventory/tests/inventory/inventory_test.cpp b/src/modules/inventory/tests/inventory/inventory_test.cpp index ca5e7794f4..7361edf682 100644 --- a/src/modules/inventory/tests/inventory/inventory_test.cpp +++ b/src/modules/inventory/tests/inventory/inventory_test.cpp @@ -1,77 +1,128 @@ -#include #include #include #include "inventory.hpp" -constexpr auto INVENTORY_DB_PATH {"TEMP.db"}; +class InventoryTest : public ::testing::Test { +protected: + void SetUp() override {} + void TearDown() override {} + Inventory &inventory = Inventory::Instance(); +}; -class InventoryTest : public ::testing::Test -{ - protected: +TEST_F(InventoryTest, SendUpdateEvent_Stateful) { + ::testing::MockFunction mockPushMessage; + inventory.SetPushMessageFunction(mockPushMessage.AsStdFunction()); - void SetUp() override {} - void TearDown() override - { - std::remove(INVENTORY_DB_PATH); - } + EXPECT_CALL(mockPushMessage, Call(::testing::_)) + .WillOnce([](const Message& msg) { + EXPECT_EQ(msg.type, MessageType::STATEFUL); + nlohmann::json expectedData = { {"key", "value"} }; + nlohmann::json expectedMetadata = { + {"type", "hardware"}, + {"operation", "update"}, + {"id", "123"} + }; + EXPECT_EQ(msg.data, expectedData); + EXPECT_EQ(nlohmann::json::parse(msg.metaData), expectedMetadata); + return 1; + }); - Inventory &inventory = Inventory::Instance(); -}; + auto inputData = R"({ + "metadata": { + "type": "hardware", + "operation": "update", + "id": "123" + }, + "data": {"key": "value"} + })"; -TEST_F(InventoryTest, SendUpdateEvent) { - ::testing::MockFunction mockPushMessage; + inventory.SendDeltaEvent(inputData); +} +TEST_F(InventoryTest, SendDeleteEvent_Stateful) { + ::testing::MockFunction mockPushMessage; inventory.SetPushMessageFunction(mockPushMessage.AsStdFunction()); EXPECT_CALL(mockPushMessage, Call(::testing::_)) - .WillOnce([](const Message& msg) - { - auto expectedData = R"({"key":"value"})"; - auto expectedMetadata = R"({"id":"123","module":"inventory","operation":"update","type":"hardware"})"; - - EXPECT_EQ(msg.data.dump(), expectedData); - EXPECT_EQ(msg.metaData, expectedMetadata); + .WillOnce([](const Message& msg) { + EXPECT_EQ(msg.type, MessageType::STATEFUL); + nlohmann::json expectedData = nlohmann::json::object(); + nlohmann::json expectedMetadata = { + {"type", "hardware"}, + {"operation", "delete"}, + {"id", "123"} + }; + EXPECT_EQ(msg.data, expectedData); + EXPECT_EQ(nlohmann::json::parse(msg.metaData), expectedMetadata); return 1; }); auto inputData = R"({ - "type": "hardware", - "operation": "update", - "id": "123", + "metadata": { + "type": "hardware", + "operation": "delete", + "id": "123" + }, "data": {"key": "value"} })"; inventory.SendDeltaEvent(inputData); } -TEST_F(InventoryTest, SendDeleteEvent) { +TEST_F(InventoryTest, SendUpdateEvent_WithStateless) { ::testing::MockFunction mockPushMessage; - inventory.SetPushMessageFunction(mockPushMessage.AsStdFunction()); EXPECT_CALL(mockPushMessage, Call(::testing::_)) - .WillOnce([](const Message& msg) - { - auto expectedData = R"({})"; - auto expectedMetadata = R"({"id":"123","module":"inventory","operation":"delete","type":"hardware"})"; - - EXPECT_EQ(msg.data.dump(), expectedData); - EXPECT_EQ(msg.metaData, expectedMetadata); + .Times(2) + .WillOnce([](const Message& msg) { + EXPECT_EQ(msg.type, MessageType::STATEFUL); + nlohmann::json expectedData = { {"key", "value"} }; + EXPECT_EQ(msg.data, expectedData); return 1; + }) + .WillOnce([](const Message& msg) { + EXPECT_EQ(msg.type, MessageType::STATELESS); + nlohmann::json expectedData = { {"alert", "high"} }; + EXPECT_EQ(msg.data, expectedData); + return 1; + }); + + auto inputData = R"({ + "metadata": { + "type": "hardware", + "operation": "update", + "id": "123" + }, + "data": {"key": "value"}, + "stateless": {"alert": "high"} + })"; + + inventory.SendDeltaEvent(inputData); +} + +TEST_F(InventoryTest, PushMessageFails_LogsWarning) { + ::testing::MockFunction mockPushMessage; + inventory.SetPushMessageFunction(mockPushMessage.AsStdFunction()); + + EXPECT_CALL(mockPushMessage, Call(::testing::_)) + .WillOnce([](const Message&) { + return 0; }); auto inputData = R"({ - "type": "hardware", - "operation": "delete", - "id": "123", + "metadata": { + "type": "hardware", + "operation": "update", + "id": "123" + }, "data": {"key": "value"} })"; inventory.SendDeltaEvent(inputData); } -int main(int argc, char** argv) -{ +int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/src/modules/inventory/tests/inventoryImp/inventoryImp_test.cpp b/src/modules/inventory/tests/inventoryImp/inventoryImp_test.cpp index aab24038d7..2a40bee4f1 100644 --- a/src/modules/inventory/tests/inventoryImp/inventoryImp_test.cpp +++ b/src/modules/inventory/tests/inventoryImp/inventoryImp_test.cpp @@ -93,38 +93,39 @@ TEST_F(InventoryImpTest, defaultCtor) { auto delta = nlohmann::json::parse(data); delta["data"].erase("@timestamp"); - delta.erase("id"); + delta["metadata"].erase("id"); + delta.erase("stateless"); wrapperDelta.callbackMock(delta.dump()); } }; const auto expectedResult1 { - R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"operation":"create","type":"hardware"})" + R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"metadata":{"module":"inventory","operation":"create","type":"hardware"}})" }; const auto expectedResult2 { - R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"operation":"create","type":"system"})" + R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"metadata":{"module":"inventory","operation":"create","type":"system"}})" }; const auto expectedResult3 { - R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"operation":"create","type":"packages"})" + R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"metadata":{"module":"inventory","operation":"create","type":"packages"}})" }; const auto expectedResult4 { - R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"operation":"create","type":"processes"})" + R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"metadata":{"module":"inventory","operation":"create","type":"processes"}})" }; const auto expectedResult5 { - R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"operation":"create","type":"hotfixes"})" + R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"metadata":{"module":"inventory","operation":"create","type":"hotfixes"}})" }; const auto expectedResult6 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; const auto expectedResult7 { - R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"operation":"create","type":"networks"})" + R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"metadata":{"module":"inventory","operation":"create","type":"networks"}})" }; EXPECT_CALL(wrapperDelta, callbackMock(expectedResult1)).Times(testing::AtLeast(1)); @@ -306,34 +307,35 @@ TEST_F(InventoryImpTest, noHardware) { auto delta = nlohmann::json::parse(data); delta["data"].erase("@timestamp"); - delta.erase("id"); + delta["metadata"].erase("id"); + delta.erase("stateless"); wrapperDelta.callbackMock(delta.dump()); } }; const auto expectedResult2 { - R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"operation":"create","type":"system"})" + R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"metadata":{"module":"inventory","operation":"create","type":"system"}})" }; const auto expectedResult3 { - R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"operation":"create","type":"packages"})" + R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"metadata":{"module":"inventory","operation":"create","type":"packages"}})" }; const auto expectedResult4 { - R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"operation":"create","type":"processes"})" + R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"metadata":{"module":"inventory","operation":"create","type":"processes"}})" }; const auto expectedResult5 { - R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"operation":"create","type":"hotfixes"})" + R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"metadata":{"module":"inventory","operation":"create","type":"hotfixes"}})" }; const auto expectedResult6 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; const auto expectedResult7 { - R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"operation":"create","type":"networks"})" + R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"metadata":{"module":"inventory","operation":"create","type":"networks"}})" }; EXPECT_CALL(wrapperDelta, callbackMock(expectedResult2)).Times(1); @@ -413,34 +415,35 @@ TEST_F(InventoryImpTest, noOs) { auto delta = nlohmann::json::parse(data); delta["data"].erase("@timestamp"); - delta.erase("id"); + delta["metadata"].erase("id"); + delta.erase("stateless"); wrapperDelta.callbackMock(delta.dump()); } }; const auto expectedResult1 { - R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"operation":"create","type":"hardware"})" + R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"metadata":{"module":"inventory","operation":"create","type":"hardware"}})" }; const auto expectedResult2 { - R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"operation":"create","type":"packages"})" + R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"metadata":{"module":"inventory","operation":"create","type":"packages"}})" }; const auto expectedResult3 { - R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"operation":"create","type":"processes"})" + R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"metadata":{"module":"inventory","operation":"create","type":"processes"}})" }; const auto expectedResult4 { - R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"operation":"create","type":"hotfixes"})" + R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"metadata":{"module":"inventory","operation":"create","type":"hotfixes"}})" }; const auto expectedResult5 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; const auto expectedResult7 { - R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"operation":"create","type":"networks"})" + R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"metadata":{"module":"inventory","operation":"create","type":"networks"}})" }; EXPECT_CALL(wrapperDelta, callbackMock(expectedResult1)).Times(1); @@ -520,34 +523,35 @@ TEST_F(InventoryImpTest, noNetwork) { auto delta = nlohmann::json::parse(data); delta["data"].erase("@timestamp"); - delta.erase("id"); + delta["metadata"].erase("id"); + delta.erase("stateless"); wrapperDelta.callbackMock(delta.dump()); } }; const auto expectedResult1 { - R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"operation":"create","type":"hardware"})" + R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"metadata":{"module":"inventory","operation":"create","type":"hardware"}})" }; const auto expectedResult2 { - R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"operation":"create","type":"system"})" + R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"metadata":{"module":"inventory","operation":"create","type":"system"}})" }; const auto expectedResult3 { - R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"operation":"create","type":"packages"})" + R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"metadata":{"module":"inventory","operation":"create","type":"packages"}})" }; const auto expectedResult4 { - R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"operation":"create","type":"processes"})" + R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"metadata":{"module":"inventory","operation":"create","type":"processes"}})" }; const auto expectedResult5 { - R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"operation":"create","type":"hotfixes"})" + R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"metadata":{"module":"inventory","operation":"create","type":"hotfixes"}})" }; const auto expectedResult6 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; EXPECT_CALL(wrapperDelta, callbackMock(expectedResult1)).Times(1); @@ -626,34 +630,35 @@ TEST_F(InventoryImpTest, noPackages) { auto delta = nlohmann::json::parse(data); delta["data"].erase("@timestamp"); - delta.erase("id"); + delta["metadata"].erase("id"); + delta.erase("stateless"); wrapperDelta.callbackMock(delta.dump()); } }; const auto expectedResult1 { - R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"operation":"create","type":"hardware"})" + R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"metadata":{"module":"inventory","operation":"create","type":"hardware"}})" }; const auto expectedResult2 { - R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"operation":"create","type":"system"})" + R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"metadata":{"module":"inventory","operation":"create","type":"system"}})" }; const auto expectedResult3 { - R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"operation":"create","type":"processes"})" + R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"metadata":{"module":"inventory","operation":"create","type":"processes"}})" }; const auto expectedResult4 { - R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"operation":"create","type":"hotfixes"})" + R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"metadata":{"module":"inventory","operation":"create","type":"hotfixes"}})" }; const auto expectedResult5 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; const auto expectedResult7 { - R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"operation":"create","type":"networks"})" + R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"metadata":{"module":"inventory","operation":"create","type":"networks"}})" }; @@ -734,34 +739,35 @@ TEST_F(InventoryImpTest, noPorts) { auto delta = nlohmann::json::parse(data); delta["data"].erase("@timestamp"); - delta.erase("id"); + delta["metadata"].erase("id"); + delta.erase("stateless"); wrapperDelta.callbackMock(delta.dump()); } }; const auto expectedResult1 { - R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"operation":"create","type":"hardware"})" + R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"metadata":{"module":"inventory","operation":"create","type":"hardware"}})" }; const auto expectedResult2 { - R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"operation":"create","type":"system"})" + R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"metadata":{"module":"inventory","operation":"create","type":"system"}})" }; const auto expectedResult3 { - R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"operation":"create","type":"packages"})" + R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"metadata":{"module":"inventory","operation":"create","type":"packages"}})" }; const auto expectedResult4 { - R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"operation":"create","type":"processes"})" + R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"metadata":{"module":"inventory","operation":"create","type":"processes"}})" }; const auto expectedResult5 { - R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"operation":"create","type":"hotfixes"})" + R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"metadata":{"module":"inventory","operation":"create","type":"hotfixes"}})" }; const auto expectedResult7 { - R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"operation":"create","type":"networks"})" + R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"metadata":{"module":"inventory","operation":"create","type":"networks"}})" }; @@ -843,42 +849,43 @@ TEST_F(InventoryImpTest, noPortsAll) { auto delta = nlohmann::json::parse(data); delta["data"].erase("@timestamp"); - delta.erase("id"); + delta["metadata"].erase("id"); + delta.erase("stateless"); wrapperDelta.callbackMock(delta.dump()); } }; const auto expectedResult1 { - R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"operation":"create","type":"hardware"})" + R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"metadata":{"module":"inventory","operation":"create","type":"hardware"}})" }; const auto expectedResult2 { - R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"operation":"create","type":"system"})" + R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"metadata":{"module":"inventory","operation":"create","type":"system"}})" }; const auto expectedResult3 { - R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"operation":"create","type":"packages"})" + R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"metadata":{"module":"inventory","operation":"create","type":"packages"}})" }; const auto expectedResult4 { - R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"operation":"create","type":"processes"})" + R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"metadata":{"module":"inventory","operation":"create","type":"processes"}})" }; const auto expectedResult5 { - R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"operation":"create","type":"hotfixes"})" + R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"metadata":{"module":"inventory","operation":"create","type":"hotfixes"}})" }; const auto expectedResult6 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; const auto expectedResult7 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; const auto expectedResult8 { - R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"operation":"create","type":"networks"})" + R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"metadata":{"module":"inventory","operation":"create","type":"networks"}})" }; EXPECT_CALL(wrapperDelta, callbackMock(expectedResult1)).Times(1); @@ -959,34 +966,35 @@ TEST_F(InventoryImpTest, noProcesses) { auto delta = nlohmann::json::parse(data); delta["data"].erase("@timestamp"); - delta.erase("id"); + delta["metadata"].erase("id"); + delta.erase("stateless"); wrapperDelta.callbackMock(delta.dump()); } }; const auto expectedResult1 { - R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"operation":"create","type":"hardware"})" + R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"metadata":{"module":"inventory","operation":"create","type":"hardware"}})" }; const auto expectedResult2 { - R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"operation":"create","type":"system"})" + R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"metadata":{"module":"inventory","operation":"create","type":"system"}})" }; const auto expectedResult3 { - R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"operation":"create","type":"packages"})" + R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"metadata":{"module":"inventory","operation":"create","type":"packages"}})" }; const auto expectedResult4 { - R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"operation":"create","type":"hotfixes"})" + R"({"data":{"package":{"hotfix":{"name":"KB12345678"}}},"metadata":{"module":"inventory","operation":"create","type":"hotfixes"}})" }; const auto expectedResult5 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; const auto expectedResult7 { - R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"operation":"create","type":"networks"})" + R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"metadata":{"module":"inventory","operation":"create","type":"networks"}})" }; EXPECT_CALL(wrapperDelta, callbackMock(expectedResult1)).Times(1); @@ -1067,34 +1075,35 @@ TEST_F(InventoryImpTest, noHotfixes) { auto delta = nlohmann::json::parse(data); delta["data"].erase("@timestamp"); - delta.erase("id"); + delta["metadata"].erase("id"); + delta.erase("stateless"); wrapperDelta.callbackMock(delta.dump()); } }; const auto expectedResult1 { - R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"operation":"create","type":"hardware"})" + R"({"data":{"host":{"cpu":{"cores":2,"name":"Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz","speed":null},"memory":{"free":2257872,"total":4972208,"used":{"percentage":54}}},"observer":{"serial_number":"Intel Corporation"}},"metadata":{"module":"inventory","operation":"create","type":"hardware"}})" }; const auto expectedResult2 { - R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"operation":"create","type":"system"})" + R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"metadata":{"module":"inventory","operation":"create","type":"system"}})" }; const auto expectedResult3 { - R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"operation":"create","type":"packages"})" + R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"metadata":{"module":"inventory","operation":"create","type":"packages"}})" }; const auto expectedResult4 { - R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"operation":"create","type":"processes"})" + R"({"data":{"process":{"args":null,"command_line":null,"group":{"id":"root"},"name":"kworker/u256:2-","parent":{"pid":2},"pid":"431625","real_group":{"id":"root"},"real_user":{"id":"root"},"saved_group":{"id":"root"},"saved_user":{"id":"root"},"start":9302261,"thread":{"id":431625},"tty":{"char_device":{"major":0}},"user":{"id":"root"}}},"metadata":{"module":"inventory","operation":"create","type":"processes"}})" }; const auto expectedResult5 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":0},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":631}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; const auto expectedResult7 { - R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"operation":"create","type":"networks"})" + R"({"data":{"host":{"ip":["172.17.0.1"],"mac":"02:42:1c:26:13:65","network":{"egress":{"bytes":0,"drops":0,"errors":0,"packets":0},"ingress":{"bytes":0,"drops":0,"errors":0,"packets":0}}},"interface":{"mtu":1500,"state":"down","type":"ethernet"},"network":{"broadcast":["172.17.255.255"],"dhcp":"unknown","gateway":[],"metric":"0","netmask":["255.255.0.0"],"protocol":null,"type":"ipv4"},"observer":{"ingress":{"interface":{"alias":"","name":"docker0"}}}},"metadata":{"module":"inventory","operation":"create","type":"networks"}})" }; EXPECT_CALL(wrapperDelta, callbackMock(expectedResult1)).Times(1); @@ -1281,28 +1290,29 @@ TEST_F(InventoryImpTest, portAllEnable) { auto delta = nlohmann::json::parse(data); delta["data"].erase("@timestamp"); - delta.erase("id"); + delta["metadata"].erase("id"); + delta.erase("stateless"); wrapper.callbackMock(delta.dump()); } }; const auto expectedResult1 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":43481},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp"},"process":{"name":null,"pid":0},"source":{"ip":["0.0.0.0"],"port":47748}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":43481},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp"},"process":{"name":null,"pid":0},"source":{"ip":["0.0.0.0"],"port":47748}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; const auto expectedResult2 { - R"({"data":{"destination":{"ip":["::"],"port":0},"file":{"inode":43482},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp6"},"process":{"name":null,"pid":0},"source":{"ip":["::"],"port":51087}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["::"],"port":0},"file":{"inode":43482},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp6"},"process":{"name":null,"pid":0},"source":{"ip":["::"],"port":51087}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; const auto expectedResult3 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":50324},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":33060}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":50324},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":33060}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; const auto expectedResult4 { - R"({"data":{"destination":{"ip":["44.238.116.130"],"port":443},"file":{"inode":122575},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"established"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["192.168.0.104"],"port":39106}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["44.238.116.130"],"port":443},"file":{"inode":122575},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"established"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["192.168.0.104"],"port":39106}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; EXPECT_CALL(wrapper, callbackMock(expectedResult1)).Times(1); @@ -1428,24 +1438,24 @@ TEST_F(InventoryImpTest, portAllDisable) { auto delta = nlohmann::json::parse(data); delta["data"].erase("@timestamp"); - delta.erase("id"); - delta.erase("id"); + delta["metadata"].erase("id"); + delta.erase("stateless"); wrapper.callbackMock(delta.dump()); } }; const auto expectedResult1 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":43481},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp"},"process":{"name":null,"pid":0},"source":{"ip":["0.0.0.0"],"port":47748}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":43481},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp"},"process":{"name":null,"pid":0},"source":{"ip":["0.0.0.0"],"port":47748}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; const auto expectedResult2 { - R"({"data":{"destination":{"ip":["::"],"port":0},"file":{"inode":43482},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp6"},"process":{"name":null,"pid":0},"source":{"ip":["::"],"port":51087}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["::"],"port":0},"file":{"inode":43482},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":null},"network":{"protocol":"udp6"},"process":{"name":null,"pid":0},"source":{"ip":["::"],"port":51087}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; const auto expectedResult3 { - R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":50324},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":33060}},"operation":"create","type":"ports"})" + R"({"data":{"destination":{"ip":["0.0.0.0"],"port":0},"file":{"inode":50324},"host":{"network":{"egress":{"queue":0},"ingress":{"queue":0}}},"interface":{"state":"listening"},"network":{"protocol":"tcp"},"process":{"name":null,"pid":0},"source":{"ip":["127.0.0.1"],"port":33060}},"metadata":{"module":"inventory","operation":"create","type":"ports"}})" }; EXPECT_CALL(wrapper, callbackMock(expectedResult1)).Times(1); @@ -1512,14 +1522,15 @@ TEST_F(InventoryImpTest, PackagesDuplicated) { auto delta = nlohmann::json::parse(data); delta["data"].erase("@timestamp"); - delta.erase("id"); + delta["metadata"].erase("id"); + delta.erase("stateless"); wrapper.callbackMock(delta.dump()); } }; const auto expectedResult1 { - R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"operation":"create","type":"packages"})" + R"({"data":{"package":{"architecture":"amd64","description":null,"installed":null,"name":"xserver-xorg","path":" ","size":411,"type":"deb","version":"1:7.7+19ubuntu14"}},"metadata":{"module":"inventory","operation":"create","type":"packages"}})" }; EXPECT_CALL(wrapper, callbackMock(expectedResult1)).Times(1); @@ -1578,13 +1589,14 @@ TEST_F(InventoryImpTest, hashId) { auto delta = nlohmann::json::parse(data); delta["data"].erase("@timestamp"); + delta.erase("stateless"); wrapperDelta.callbackMock(delta.dump()); } }; const auto expectedResult2 { - R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"id":"6bd3291be0d2314de0329e8ac36be434a085eb32","operation":"create","type":"system"})" + R"({"data":{"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}},"metadata":{"id":"6bd3291be0d2314de0329e8ac36be434a085eb32","module":"inventory","operation":"create","type":"system"}})" }; EXPECT_CALL(wrapperDelta, callbackMock(expectedResult2)).Times(1); @@ -1629,6 +1641,74 @@ TEST_F(InventoryImpTest, hashId) } +TEST_F(InventoryImpTest, statelessMessage) +{ + const auto spInfoWrapper{std::make_shared()}; + + EXPECT_CALL(*spInfoWrapper, os()).WillRepeatedly(Return(nlohmann::json::parse( + R"({"architecture":"x86_64","scan_time":"2020/12/28 21:49:50", "hostname":"UBUNTU","os_build":"7601","os_major":"6","os_minor":"1","os_name":"Microsoft Windows 7","os_release":"sp1","os_version":"6.1.7601"})" + ))); + + CallbackMock wrapperDelta; + std::function callbackDataDelta + { + [&wrapperDelta](const std::string & data) + { + auto delta = nlohmann::json::parse(data); + delta.erase("data"); + delta.erase("metadata"); + delta["stateless"]["event"].erase("created"); + wrapperDelta.callbackMock(delta.dump()); + } + }; + + const auto expectedResult1 + { + R"({"stateless":{"event":{"action":"system-detected","category":["host"],"reason":"System UBUNTU is running OS version 6.1.7601","type":["info"]},"host":{"architecture":"x86_64","hostname":"UBUNTU","os":{"full":null,"kernel":"7601","name":"Microsoft Windows 7","platform":null,"type":null,"version":"6.1.7601"}}}})" + }; + + EXPECT_CALL(wrapperDelta, callbackMock(expectedResult1)).Times(1); + + std::string inventoryConfig = R"( + inventory: + enabled: true + interval: 3600 + scan_on_start: true + hardware: false + system: true + networks: false + packages: false + ports: false + ports_all: false + processes: false + hotfixes: false + )"; + auto configParser = std::make_shared(inventoryConfig); + Inventory::Instance().Setup(configParser); + + std::thread t + { + [&spInfoWrapper, &callbackDataDelta]() + { + Inventory::Instance().Init(spInfoWrapper, + callbackDataDelta, + INVENTORY_DB_PATH, + "", + ""); + Inventory::Instance().SetAgentUUID("1234"); + } + }; + + std::this_thread::sleep_for(std::chrono::seconds(1)); + Inventory::Instance().Stop(); + + if (t.joinable()) + { + t.join(); + } + +} + int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); From ae6615bcc2ca6de07ea55dbecaf083a6e3054425 Mon Sep 17 00:00:00 2001 From: cborla Date: Thu, 16 Jan 2025 11:44:26 -0300 Subject: [PATCH 08/10] feat: split NotifyChange method in 4 functions --- src/modules/inventory/include/inventory.hpp | 4 + src/modules/inventory/src/inventoryImp.cpp | 135 +++++++++----------- 2 files changed, 61 insertions(+), 78 deletions(-) diff --git a/src/modules/inventory/include/inventory.hpp b/src/modules/inventory/include/inventory.hpp index 1a665edd67..32fa47e291 100644 --- a/src/modules/inventory/include/inventory.hpp +++ b/src/modules/inventory/include/inventory.hpp @@ -67,6 +67,10 @@ class Inventory { void UpdateChanges(const std::string& table, const nlohmann::json& values, const bool isFirstScan); void NotifyChange(ReturnTypeCallback result, const nlohmann::json& data, const std::string& table); + void ProcessEvent(ReturnTypeCallback result, const nlohmann::json& item, const std::string& table); + nlohmann::json GenerateMessage(ReturnTypeCallback result, const nlohmann::json& item, const std::string& table); + void NotifyEvent(ReturnTypeCallback result, nlohmann::json& msg, const nlohmann::json& item, const std::string& table); + void TryCatchTask(const std::function& task) const; void ScanHardware(); void ScanSystem(); diff --git a/src/modules/inventory/src/inventoryImp.cpp b/src/modules/inventory/src/inventoryImp.cpp index 56a852cb9d..76d888c77b 100644 --- a/src/modules/inventory/src/inventoryImp.cpp +++ b/src/modules/inventory/src/inventoryImp.cpp @@ -323,100 +323,79 @@ void Inventory::NotifyChange(ReturnTypeCallback result, const nlohmann::json& da if (DB_ERROR == result) { LogErrorInventory(data.dump()); + return; } - else if (m_notify && !m_stopping) + + if (!m_notify || m_stopping) { + return; + } - if (data.is_array()) + if (data.is_array()) + { + for (const auto& item : data) { - for (const auto& item : data) - { - // LCOV_EXCL_START - nlohmann::json msg{ - {"metadata", { - {"type", table}, - {"operation", OPERATION_MAP.at(result)}, - {"module", Name()} - }} - }; - - msg["data"] = EcsData(result == MODIFIED ? item["new"] : item, table); - nlohmann::json oldData = (result == MODIFIED) ? EcsData(item["old"], table, false) : nlohmann::json{}; - - msg["metadata"]["id"] = CalculateHashId(msg["data"], table); - - if (msg["metadata"]["id"].is_string() && msg["metadata"]["id"].get().size() <= MAX_ID_SIZE) { - - nlohmann::json stateless; - stateless = GenerateStatelessEvent(OPERATION_MAP.at(result), table, msg["data"]); + ProcessEvent(result, item, table); + } + } + else + { + ProcessEvent(result, data, table); + } +} - nlohmann::json eventWithChanges; - eventWithChanges = msg["data"]; - if (!oldData.empty()) - { - stateless["event"]["changed_fields"] = AddPreviousFields(eventWithChanges, oldData); - } +void Inventory::ProcessEvent(ReturnTypeCallback result, const nlohmann::json& item, const std::string& table) +{ + nlohmann::json msg = GenerateMessage(result, item, table); - stateless.update(eventWithChanges); - msg["stateless"] = stateless; - msg["data"]["@timestamp"] = m_scanTime; + if (msg["metadata"]["id"].is_string() && msg["metadata"]["id"].get().size() <= MAX_ID_SIZE) + { + NotifyEvent(result, msg, item, table); + } + else + { + LogWarn("Event discarded for exceeding maximum size allowed in id field."); + LogTrace("Event discarded: {}", msg.dump()); + } +} - const auto msgToSend{msg.dump()}; - m_reportDiffFunction(msgToSend); - } - else - { - LogWarn("Event discarded for exceeding maximum size allowed in id field."); - LogTrace("Event discarded: {}", msg.dump()); - } - // LCOV_EXCL_STOP - } - } - else - { - // LCOV_EXCL_START - nlohmann::json msg{ - {"metadata", { - {"type", table}, - {"operation", OPERATION_MAP.at(result)}, - {"module", Name()} - }} - }; +nlohmann::json Inventory::GenerateMessage(ReturnTypeCallback result, const nlohmann::json& item, const std::string& table) +{ + nlohmann::json msg{ + {"metadata", { + {"type", table}, + {"operation", OPERATION_MAP.at(result)}, + {"module", Name()} + }} + }; - msg["data"] = EcsData(result == MODIFIED ? data["new"] : data, table); - nlohmann::json oldData = (result == MODIFIED) ? EcsData(data["old"], table, false) : nlohmann::json{}; + msg["data"] = EcsData(result == MODIFIED ? item["new"] : item, table); + msg["metadata"]["id"] = CalculateHashId(msg["data"], table); - msg["metadata"]["id"] = CalculateHashId(msg["data"], table); + return msg; +} - if (msg["metadata"]["id"].is_string() && msg["metadata"]["id"].get().size() <= MAX_ID_SIZE) { +void Inventory::NotifyEvent(ReturnTypeCallback result, nlohmann::json& msg, const nlohmann::json& item, const std::string& table) +{ + nlohmann::json oldData = (result == MODIFIED) ? EcsData(item["old"], table, false) : nlohmann::json{}; - nlohmann::json stateless; - stateless = GenerateStatelessEvent(OPERATION_MAP.at(result), table, msg["data"]); + nlohmann::json stateless = GenerateStatelessEvent(OPERATION_MAP.at(result), table, msg["data"]); + nlohmann::json eventWithChanges = msg["data"]; - nlohmann::json eventWithChanges; - eventWithChanges = msg["data"]; - if (!oldData.empty()) - { - stateless["event"]["changed_fields"] = AddPreviousFields(eventWithChanges, oldData); - } + if (!oldData.empty()) + { + stateless["event"]["changed_fields"] = AddPreviousFields(eventWithChanges, oldData); + } - stateless.update(eventWithChanges); - msg["stateless"] = stateless; - msg["data"]["@timestamp"] = m_scanTime; + stateless.update(eventWithChanges); + msg["stateless"] = stateless; + msg["data"]["@timestamp"] = m_scanTime; - const auto msgToSend{msg.dump()}; - m_reportDiffFunction(msgToSend); - } - else - { - LogWarn("Event discarded for exceeding maximum size allowed in id field."); - LogTrace("Event discarded: {}", msg.dump()); - } - // LCOV_EXCL_STOP - } - } + const auto msgToSend = msg.dump(); + m_reportDiffFunction(msgToSend); } + void Inventory::UpdateChanges(const std::string& table, const nlohmann::json& values, const bool isFirstScan) From 2f0d25b54ff408127a9ea6fba0a85ee7ca03f160 Mon Sep 17 00:00:00 2001 From: cborla Date: Thu, 16 Jan 2025 18:20:18 -0300 Subject: [PATCH 09/10] feat: convert GenerateStatelessEvent into a class --- src/modules/inventory/CMakeLists.txt | 3 +- src/modules/inventory/src/inventoryImp.cpp | 160 +--------------- src/modules/inventory/src/statelessEvent.cpp | 171 ++++++++++++++++++ src/modules/inventory/src/statelessEvent.hpp | 27 +++ src/modules/inventory/tests/CMakeLists.txt | 1 + .../tests/statelessEvent/CMakeLists.txt | 26 +++ .../statelessEvent/statelessEvent_test.cpp | 78 ++++++++ 7 files changed, 309 insertions(+), 157 deletions(-) create mode 100644 src/modules/inventory/src/statelessEvent.cpp create mode 100644 src/modules/inventory/src/statelessEvent.hpp create mode 100644 src/modules/inventory/tests/statelessEvent/CMakeLists.txt create mode 100644 src/modules/inventory/tests/statelessEvent/statelessEvent_test.cpp diff --git a/src/modules/inventory/CMakeLists.txt b/src/modules/inventory/CMakeLists.txt index 995b89cb04..889ecbc670 100644 --- a/src/modules/inventory/CMakeLists.txt +++ b/src/modules/inventory/CMakeLists.txt @@ -16,7 +16,8 @@ find_package(Boost REQUIRED COMPONENTS asio beast) add_library(Inventory src/inventory.cpp src/inventoryImp.cpp - src/inventoryNormalizer.cpp) + src/inventoryNormalizer.cpp + src/statelessEvent.cpp) if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") target_compile_options(Inventory PRIVATE /WX-) diff --git a/src/modules/inventory/src/inventoryImp.cpp b/src/modules/inventory/src/inventoryImp.cpp index 76d888c77b..dca1943e7a 100644 --- a/src/modules/inventory/src/inventoryImp.cpp +++ b/src/modules/inventory/src/inventoryImp.cpp @@ -7,14 +7,12 @@ #include #include #include +#include "commonDefs.h" +#include "statelessEvent.hpp" constexpr std::time_t INVENTORY_DEFAULT_INTERVAL { 3600000 }; constexpr size_t MAX_ID_SIZE = 512; -constexpr int BYTES_IN_KILOBYTE = 1024; -constexpr int KILOBYTES_IN_MEGABYTE = 1024; -constexpr int BYTES_IN_MEGABYTE = BYTES_IN_KILOBYTE * KILOBYTES_IN_MEGABYTE; - constexpr auto QUEUE_SIZE { 4096 @@ -1297,156 +1295,6 @@ nlohmann::json Inventory::AddPreviousFields(nlohmann::json& current, const nlohm } nlohmann::json Inventory::GenerateStatelessEvent(const std::string& operation, const std::string& type, const nlohmann::json& data) { - nlohmann::json event; - std::string action, reason; - std::string created = m_scanTime; - - if (type == "packages") { - std::string packageName = data["package"]["name"]; - std::string version = data["package"]["version"]; - - if (operation == "create") { - action = "package-installed"; - reason = "Package " + packageName + " (version " + version + ") was installed"; - } else if (operation == "update") { - reason = "Package " + packageName + " updated"; - action = "package-updated"; - } else if (operation == "remove") { - action = "package-removed"; - reason = "Package " + packageName + " (version " + version + ") was removed"; - } - - event["event"] = { - {"action", action}, - {"category", {"package"}}, - {"type", {operation == "create" ? "installation" : operation == "update" ? "change" : "deletion"}}, - {"created", created}, - {"reason", reason} - }; - } else if (type == "ports") { - int srcPort = data["source"]["port"]; - int destPort = data["destination"]["port"]; - - if (operation == "create") { - action = "port-detected"; - reason = "New connection established from source port " + std::to_string(srcPort) + " to destination port " + std::to_string(destPort); - } else if (operation == "update") { - action = "port-updated"; - reason = "Change for the connection from source port " + std::to_string(srcPort) + " to destination port " + std::to_string(destPort); - } else if (operation == "remove") { - action = "port-closed"; - reason = "Connection from source port " + std::to_string(srcPort) + " to destination port " + std::to_string(destPort) + " was closed"; - } - - event["event"] = { - {"action", action}, - {"category", {"network"}}, - {"type", {operation == "create" ? "connection" : operation == "update" ? "change" : "end"}}, - {"created", created}, - {"reason", reason} - }; - } else if (type == "hardware") { - std::string cpuName = data["host"]["cpu"]["name"]; - int memoryTotalGB = data["host"]["memory"]["total"].get() / BYTES_IN_MEGABYTE; - std::string serialNumber = data["observer"]["serial_number"]; - - if (operation == "create") { - action = "hardware-detected"; - reason = "New hardware detected: " + cpuName + " with " + std::to_string(memoryTotalGB) + " GB memory"; - } else if (operation == "update") { - action = "hardware-updated"; - reason = "Hardware changed"; - } else if (operation == "remove") { - action = "hardware-removed"; - reason = "Hardware with serial number " + serialNumber + " was removed"; - } - - event["event"] = { - {"action", action}, - {"category", {"host"}}, - {"type", {operation == "create" ? "info" : operation == "update" ? "change" : "deletion"}}, - {"created", created}, - {"reason", reason} - }; - } else if (type == "networks") { - std::string interface = data["observer"]["ingress"]["interface"]["name"]; - - if (operation == "create") { - action = "network-interface-detected"; - reason = "New network interface " + interface + " detected"; - } else if (operation == "update") { - action = "network-interface-updated"; - reason = "Network interface " + interface + "updated"; - } else if (operation == "remove") { - action = "network-interface-removed"; - reason = "Network interface " + interface + " was removed"; - } - - event["event"] = { - {"action", action}, - {"category", {"network"}}, - {"type", {operation == "create" ? "info" : operation == "update" ? "change" : "deletion"}}, - {"created", created}, - {"reason", reason} - }; - } else if (type == "processes") { - std::string processName = data["process"]["name"]; - std::string pid = data["process"]["pid"]; - - if (operation == "create") { - action = "process-started"; - reason = "Process " + processName + " (PID: " + pid + ") was started"; - } else if (operation == "update") { - action = "process-updated"; - reason = "Process " + processName + " (PID: " + pid + ") was updated"; - } else if (operation == "remove") { - action = "process-stopped"; - reason = "Process " + processName + " (PID: " + pid + ") was stopped"; - } - - event["event"] = { - {"action", action}, - {"category", {"process"}}, - {"type", {operation == "create" ? "start" : operation == "update" ? "change" : "end"}}, - {"created", created}, - {"reason", reason} - }; - } else if (type == "system") { - std::string hostname = data["host"]["hostname"]; - std::string osVersion = data["host"]["os"]["version"]; - - action = (operation == "update") ? "system-updated" : "system-detected"; - reason = "System " + hostname + " is running OS version " + osVersion; - - event["event"] = { - {"action", action}, - {"category", {"host"}}, - {"type", {operation == "update" ? "change" : "info"}}, - {"created", created}, - {"reason", reason} - }; - } else if (type == "hotfixes") { - std::string hotfixID = data["package"]["hotfix"]["name"]; - - if (operation == "create") { - action = "hotfix-installed"; - reason = "Hotfix " + hotfixID + " was installed"; - } else if (operation == "update") { - action = "hotfix-updated"; - reason = "Hotfix " + hotfixID + " was updated"; - } else if (operation == "remove") { - action = "hotfix-removed"; - reason = "Hotfix " + hotfixID + " was removed"; - } - - event["event"] = { - {"action", action}, - {"category", {"hotfix"}}, - {"type", {operation == "create" ? "installation" : "deletion"}}, - {"created", created}, - {"reason", reason} - }; - } - - return event; + auto event = CreateStatelessEvent(type, operation, m_scanTime, data); + return event ? event->generate() : nlohmann::json{}; } diff --git a/src/modules/inventory/src/statelessEvent.cpp b/src/modules/inventory/src/statelessEvent.cpp new file mode 100644 index 0000000000..1ed9e5ebd6 --- /dev/null +++ b/src/modules/inventory/src/statelessEvent.cpp @@ -0,0 +1,171 @@ +#include "statelessEvent.hpp" + +constexpr int BYTES_IN_KILOBYTE = 1024; +constexpr int KILOBYTES_IN_MEGABYTE = 1024; +constexpr int BYTES_IN_MEGABYTE = BYTES_IN_KILOBYTE * KILOBYTES_IN_MEGABYTE; + +StatelessEvent::StatelessEvent(std::string op, std::string time, nlohmann::json d) + : operation(std::move(op)), created(std::move(time)), data(std::move(d)) {} + +nlohmann::json NetworkEvent::generate() const { + std::string interface = (data.contains("observer") && + data["observer"].contains("ingress") && + data["observer"]["ingress"].contains("interface") && + data["observer"]["ingress"]["interface"].contains("name") && + !data["observer"]["ingress"]["interface"]["name"].is_null()) + ? data["observer"]["ingress"]["interface"]["name"].get() + : ""; + + std::string action, reason; + + if (operation == "create") { + action = "network-interface-detected"; + reason = "New network interface " + interface + " detected"; + } else if (operation == "update") { + action = "network-interface-updated"; + reason = "Network interface " + interface + " updated"; + } else { + action = "network-interface-removed"; + reason = "Network interface " + interface + " was removed"; + } + + return {{"event", {{"action", action}, {"category", {"network"}}, {"type", {operation == "create" ? "info" : operation == "update" ? "change" : "deletion"}}, {"created", created}, {"reason", reason}}}}; +} + +nlohmann::json PackageEvent::generate() const { + + std::string packageName = (data.contains("package") && data["package"].contains("name") && !data["package"]["name"].is_null()) + ? data["package"]["name"].get() : ""; + std::string version = (data.contains("package") && data["package"].contains("version") && !data["package"]["version"].is_null()) + ? data["package"]["version"].get() : ""; + + std::string action, reason; + + if (operation == "create") { + action = "package-installed"; + reason = "Package " + packageName + " (version " + version + ") was installed"; + } else if (operation == "update") { + action = "package-updated"; + reason = "Package " + packageName + " updated"; + } else { + action = "package-removed"; + reason = "Package " + packageName + " (version " + version + ") was removed"; + } + + return {{"event", {{"action", action}, {"category", {"package"}}, {"type", {operation == "create" ? "installation" : operation == "update" ? "change" : "deletion"}}, {"created", created}, {"reason", reason}}}}; +} + +nlohmann::json HotfixEvent::generate() const { + std::string hotfixID = (data.contains("package") && data["package"].contains("hotfix") && data["package"]["hotfix"].contains("name") && !data["package"]["hotfix"]["name"].is_null()) + ? data["package"]["hotfix"]["name"].get() : ""; + + std::string action, reason; + + if (operation == "create") { + action = "hotfix-installed"; + reason = "Hotfix " + hotfixID + " was installed"; + } else if (operation == "update") { + action = "hotfix-updated"; + reason = "Hotfix " + hotfixID + " was updated"; + } else { + action = "hotfix-removed"; + reason = "Hotfix " + hotfixID + " was removed"; + } + + return {{"event", {{"action", action}, {"category", {"hotfix"}}, {"type", {operation == "create" ? "installation" : "deletion"}}, {"created", created}, {"reason", reason}}}}; +} + +nlohmann::json PortEvent::generate() const { + + int srcPort = (data.contains("source") && data["source"].contains("port") && !data["source"]["port"].is_null()) + ? data["source"]["port"].get() : 0; + int destPort = (data.contains("destination") && data["destination"].contains("port") && !data["destination"]["port"].is_null()) + ? data["destination"]["port"].get() : 0; + + std::string action, reason; + + if (operation == "create") { + action = "port-detected"; + reason = "New connection from source port " + std::to_string(srcPort) + " to destination port " + std::to_string(destPort); + } else if (operation == "update") { + action = "port-updated"; + reason = "Updated connection from source port " + std::to_string(srcPort) + " to destination port " + std::to_string(destPort); + } else { + action = "port-closed"; + reason = "Closed connection from source port " + std::to_string(srcPort) + " to destination port " + std::to_string(destPort); + } + + return {{"event", {{"action", action}, {"category", {"network"}}, {"type", {operation == "create" ? "connection" : operation == "update" ? "change" : "end"}}, {"created", created}, {"reason", reason}}}}; +} + +nlohmann::json ProcessEvent::generate() const { + std::string processName = (data.contains("process") && data["process"].contains("name") && !data["process"]["name"].is_null()) + ? data["process"]["name"].get() : ""; + std::string pid = (data.contains("process") && data["process"].contains("pid") && !data["process"]["pid"].is_null()) + ? data["process"]["name"].get() : ""; + + std::string action, reason; + + if (operation == "create") { + action = "process-started"; + reason = "Process " + processName + " (PID: " + pid + ") was started"; + } else if (operation == "update") { + action = "process-updated"; + reason = "Process " + processName + " (PID: " + pid + ") was updated"; + } else { + action = "process-stopped"; + reason = "Process " + processName + " (PID: " + pid + ") was stopped"; + } + + return {{"event", {{"action", action}, {"category", {"process"}}, {"type", {operation == "create" ? "start" : operation == "update" ? "change" : "end"}}, {"created", created}, {"reason", reason}}}}; +} + +nlohmann::json SystemEvent::generate() const { + + std::string hostname = (data.contains("host") && data["host"].contains("hostname") && !data["host"]["hostname"].is_null()) + ? data["host"]["hostname"].get() : ""; + std::string osVersion = (data.contains("host") && data["host"].contains("os") && data["host"]["os"].contains("version") && !data["host"]["os"]["version"].is_null()) + ? data["host"]["os"]["version"].get() : ""; + + std::string action = (operation == "update") ? "system-updated" : "system-detected"; + std::string reason = "System " + hostname + " is running OS version " + osVersion; + + return {{"event", {{"action", action}, {"category", {"host"}}, {"type", {operation == "update" ? "change" : "info"}}, {"created", created}, {"reason", reason}}}}; +} + +nlohmann::json HardwareEvent::generate() const { + + std::string cpuName = (data.contains("host") && data["host"].contains("cpu") && data["host"]["cpu"].contains("name") && !data["host"]["cpu"]["name"].is_null()) + ? data["host"]["cpu"]["name"].get() : ""; + int memoryTotalGB = (data.contains("host") && data["host"].contains("memory") && data["host"]["memory"].contains("total") && !data["host"]["memory"]["total"].is_null()) + ? data["host"]["memory"]["total"].get() / BYTES_IN_MEGABYTE : 0; + std::string serialNumber = (data.contains("observer") && data["observer"].contains("serial_number") && !data["observer"]["serial_number"].is_null()) + ? data["observer"]["serial_number"].get() : ""; + + std::string action, reason; + + if (operation == "create") { + action = "hardware-detected"; + reason = "New hardware detected: " + cpuName + " with " + std::to_string(memoryTotalGB) + " GB memory"; + } else if (operation == "update") { + action = "hardware-updated"; + reason = "Hardware changed"; + } else if (operation == "remove") { + action = "hardware-removed"; + reason = "Hardware with serial number " + serialNumber + " was removed"; + } + + return {{"event", {{"action", action}, {"category", {"host"}}, {"type", {operation == "create" ? "start" : operation == "update" ? "change" : "removed"}}, {"created", created}, {"reason", reason}}}}; +} + +std::unique_ptr CreateStatelessEvent(const std::string& type, const std::string& operation, const std::string& created, const nlohmann::json& data) { + if (type == "networks") return std::make_unique(operation, created, data); + if (type == "packages") return std::make_unique(operation, created, data); + if (type == "hotfixes") return std::make_unique(operation, created, data); + if (type == "ports") return std::make_unique(operation, created, data); + if (type == "processes") return std::make_unique(operation, created, data); + if (type == "system") return std::make_unique(operation, created, data); + if (type == "hardware") return std::make_unique(operation, created, data); + + return nullptr; +} diff --git a/src/modules/inventory/src/statelessEvent.hpp b/src/modules/inventory/src/statelessEvent.hpp new file mode 100644 index 0000000000..e12fd8acd5 --- /dev/null +++ b/src/modules/inventory/src/statelessEvent.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +class StatelessEvent { +protected: + std::string operation; + std::string created; + nlohmann::json data; + +public: + StatelessEvent(std::string op, std::string time, nlohmann::json d); + virtual nlohmann::json generate() const = 0; + virtual ~StatelessEvent() = default; +}; + +class NetworkEvent : public StatelessEvent { public: using StatelessEvent::StatelessEvent; nlohmann::json generate() const override; }; +class PackageEvent : public StatelessEvent { public: using StatelessEvent::StatelessEvent; nlohmann::json generate() const override; }; +class HotfixEvent : public StatelessEvent { public: using StatelessEvent::StatelessEvent; nlohmann::json generate() const override; }; +class PortEvent : public StatelessEvent { public: using StatelessEvent::StatelessEvent; nlohmann::json generate() const override; }; +class ProcessEvent : public StatelessEvent { public: using StatelessEvent::StatelessEvent; nlohmann::json generate() const override; }; +class SystemEvent : public StatelessEvent { public: using StatelessEvent::StatelessEvent; nlohmann::json generate() const override; }; +class HardwareEvent : public StatelessEvent { public: using StatelessEvent::StatelessEvent; nlohmann::json generate() const override; }; + +std::unique_ptr CreateStatelessEvent(const std::string& type, const std::string& operation, const std::string& created, const nlohmann::json& data); diff --git a/src/modules/inventory/tests/CMakeLists.txt b/src/modules/inventory/tests/CMakeLists.txt index 7493e4f93c..9e0ca46be9 100644 --- a/src/modules/inventory/tests/CMakeLists.txt +++ b/src/modules/inventory/tests/CMakeLists.txt @@ -5,3 +5,4 @@ project(unit_tests) add_subdirectory(inventory) add_subdirectory(inventoryImp) add_subdirectory(invNormalizer) +add_subdirectory(statelessEvent) diff --git a/src/modules/inventory/tests/statelessEvent/CMakeLists.txt b/src/modules/inventory/tests/statelessEvent/CMakeLists.txt new file mode 100644 index 0000000000..f6d8adc9a8 --- /dev/null +++ b/src/modules/inventory/tests/statelessEvent/CMakeLists.txt @@ -0,0 +1,26 @@ +find_package(GTest CONFIG REQUIRED) + +add_executable(statelessEvent_unit_test statelessEvent_test.cpp) +configure_target(statelessEvent_unit_test) + +target_include_directories(statelessEvent_unit_test PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/../include + ${CMAKE_CURRENT_SOURCE_DIR}/../src/inventory/events +) + +if(NOT WIN32) + target_link_libraries(statelessEvent_unit_test PRIVATE + Inventory + GTest::gtest + GTest::gtest_main + pthread + ) +else() + target_link_libraries(statelessEvent_unit_test PRIVATE + Inventory + GTest::gtest + GTest::gtest_main + ) +endif() + +add_test(NAME StatelessEventUnitTest COMMAND statelessEvent_unit_test) diff --git a/src/modules/inventory/tests/statelessEvent/statelessEvent_test.cpp b/src/modules/inventory/tests/statelessEvent/statelessEvent_test.cpp new file mode 100644 index 0000000000..9e208ddc30 --- /dev/null +++ b/src/modules/inventory/tests/statelessEvent/statelessEvent_test.cpp @@ -0,0 +1,78 @@ +#include +#include "../src/statelessEvent.hpp" + +TEST(PackageEventTest, CreatePackageEvent) { + nlohmann::json data = { + {"package", {{"name", "nginx"}, {"version", "1.18.0"}}} + }; + + PackageEvent event("create", "2024-01-16T00:00:00Z", data); + nlohmann::json result = event.generate(); + + EXPECT_EQ(result["event"]["action"], "package-installed"); + EXPECT_EQ(result["event"]["category"][0], "package"); + EXPECT_EQ(result["event"]["reason"], "Package nginx (version 1.18.0) was installed"); +} + +TEST(NetworkEventTest, CreateNetworkEvent) { + nlohmann::json data = { + {"observer", {{"ingress", {{"interface", {{"name", "eth0"}}}}}}} + }; + + NetworkEvent event("create", "2024-01-16T00:00:00Z", data); + nlohmann::json result = event.generate(); + + EXPECT_EQ(result["event"]["action"], "network-interface-detected"); + EXPECT_EQ(result["event"]["category"][0], "network"); + EXPECT_EQ(result["event"]["reason"], "New network interface eth0 detected"); +} + +TEST(HotfixEventTest, RemoveHotfixEvent) { + nlohmann::json data = { + {"package", {{"hotfix", {{"name", "KB123456"}}}}} + }; + + HotfixEvent event("remove", "2024-01-16T00:00:00Z", data); + nlohmann::json result = event.generate(); + + EXPECT_EQ(result["event"]["action"], "hotfix-removed"); + EXPECT_EQ(result["event"]["category"][0], "hotfix"); + EXPECT_EQ(result["event"]["reason"], "Hotfix KB123456 was removed"); +} + +TEST(PortEventTest, UpdatePortEvent) { + nlohmann::json data = nlohmann::json::parse(R"( + { + "source": { "port": 8080 }, + "destination": { "port": 443 } + } + )"); + + PortEvent event("update", "2024-01-16T00:00:00Z", data); + nlohmann::json result = event.generate(); + + EXPECT_EQ(result["event"]["action"], "port-updated"); + EXPECT_EQ(result["event"]["category"][0], "network"); + EXPECT_EQ(result["event"]["type"][0], "change"); + EXPECT_EQ(result["event"]["reason"], "Updated connection from source port 8080 to destination port 443"); +} + +TEST(SystemEventTest, CreateSystemEvent) { + nlohmann::json data = { + {"host", {{"hostname", "server01"}, {"os", {{"version", "Ubuntu 22.04"}}}}} + }; + + SystemEvent event("create", "2024-01-16T00:00:00Z", data); + nlohmann::json result = event.generate(); + + EXPECT_EQ(result["event"]["action"], "system-detected"); + EXPECT_EQ(result["event"]["category"][0], "host"); + EXPECT_EQ(result["event"]["type"][0], "info"); + EXPECT_EQ(result["event"]["reason"], "System server01 is running OS version Ubuntu 22.04"); + EXPECT_EQ(result["event"]["created"], "2024-01-16T00:00:00Z"); +} + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From 84a69fede5b1239b69a83a6ac40debdf1356438c Mon Sep 17 00:00:00 2001 From: nbertoldo Date: Fri, 17 Jan 2025 13:10:39 -0300 Subject: [PATCH 10/10] feat: modify dbsync to allow storing null values --- .../src/network/networkBSDWrapper.h | 12 +- .../src/network/networkLinuxWrapper.h | 14 +-- .../src/network/networkWindowsWrapper.h | 16 +-- .../src/packages/appxWindowsWrapper.h | 10 +- .../data_provider/src/packages/brewWrapper.h | 14 +-- .../src/packages/macportsWrapper.h | 16 +-- .../src/packages/packageLinuxParserHelper.h | 30 ++--- .../packages/packageLinuxRpmParserHelper.h | 6 +- .../packageLinuxRpmParserHelperLegacy.h | 12 +- .../src/packages/packagesNPM.hpp | 14 +-- .../src/packages/packagesPYPI.hpp | 14 +-- .../data_provider/src/packages/pkgWrapper.h | 8 +- .../data_provider/src/ports/portBSDWrapper.h | 6 +- .../src/ports/portLinuxWrapper.h | 14 +-- .../src/ports/portWindowsWrapper.h | 6 +- src/common/data_provider/src/sharedDefs.h | 1 + src/common/data_provider/src/sysInfoLinux.cpp | 8 +- src/common/data_provider/src/sysInfoMac.cpp | 2 +- src/common/data_provider/src/sysInfoUnix.cpp | 2 +- src/common/data_provider/src/sysInfoWin.cpp | 12 +- .../sysInfoPackageLinuxParserRPM_test.cpp | 20 +-- .../sysInfoPackagesLinuxHelper_test.cpp | 12 +- .../sysInfoPackagesMAC/pkgWrapper_test.cpp | 80 ++++++------ .../dbsync/src/sqlite/isqlite_wrapper.h | 1 + .../dbsync/src/sqlite/sqlite_dbengine.cpp | 116 ++++++++++++++---- .../dbsync/src/sqlite/sqlite_dbengine.h | 8 +- .../dbsync/src/sqlite/sqlite_wrapper.cpp | 6 + src/common/dbsync/src/sqlite/sqlite_wrapper.h | 1 + .../dbsync/tests/dbengine/dbengine_test.cpp | 10 +- .../dbsync/tests/mocks/sqlitewrapper_mock.h | 5 +- src/modules/inventory/src/inventoryImp.cpp | 2 +- 31 files changed, 282 insertions(+), 196 deletions(-) diff --git a/src/common/data_provider/src/network/networkBSDWrapper.h b/src/common/data_provider/src/network/networkBSDWrapper.h index f84fbf48ad..7d0deaa80d 100644 --- a/src/common/data_provider/src/network/networkBSDWrapper.h +++ b/src/common/data_provider/src/network/networkBSDWrapper.h @@ -118,7 +118,7 @@ class NetworkBSDInterface final : public INetworkInterfaceWrapper void gateway(nlohmann::json& network) const override { - network["gateway"] = EMPTY_VALUE; + network["gateway"] = UNKNOWN_VALUE; size_t tableSize { 0 }; int mib[] = { CTL_NET, AF_ROUTE, 0, AF_UNSPEC, NET_RT_FLAGS, RTF_UP | RTF_GATEWAY }; @@ -158,22 +158,22 @@ class NetworkBSDInterface final : public INetworkInterfaceWrapper void metrics(nlohmann::json& network) const override { - network["metric"] = EMPTY_VALUE; + network["metric"] = UNKNOWN_VALUE; } void metricsV6(nlohmann::json& network) const override { - network["metric"] = EMPTY_VALUE; + network["metric"] = UNKNOWN_VALUE; } void dhcp(nlohmann::json& network) const override { - network["dhcp"] = EMPTY_VALUE; + network["dhcp"] = UNKNOWN_VALUE; } void mtu(nlohmann::json& network) const override { - network["mtu"] = EMPTY_VALUE; + network["mtu"] = UNKNOWN_VALUE; if(m_interfaceAddress->ifa_data) { network["mtu"] = reinterpret_cast(m_interfaceAddress->ifa_data)->ifi_mtu; @@ -221,7 +221,7 @@ class NetworkBSDInterface final : public INetworkInterfaceWrapper void MAC(nlohmann::json& network) const override { - network["mac"] = EMPTY_VALUE; + network["mac"] = UNKNOWN_VALUE; auto sdl { reinterpret_cast(m_interfaceAddress->ifa_addr) }; std::stringstream ss; diff --git a/src/common/data_provider/src/network/networkLinuxWrapper.h b/src/common/data_provider/src/network/networkLinuxWrapper.h index 1e8c5fa7cf..dd2a1cfe5f 100644 --- a/src/common/data_provider/src/network/networkLinuxWrapper.h +++ b/src/common/data_provider/src/network/networkLinuxWrapper.h @@ -321,7 +321,7 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper void broadcast(nlohmann::json& network) const override { - network["broadcast"] = EMPTY_VALUE; + network["broadcast"] = UNKNOWN_VALUE; if (m_interfaceAddress->ifa_ifu.ifu_broadaddr) { @@ -357,7 +357,7 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper { m_interfaceAddress->ifa_ifu.ifu_broadaddr ? network["broadcast"] = getNameInfo(m_interfaceAddress->ifa_ifu.ifu_broadaddr, sizeof(struct sockaddr_in6)) : - network["broadcast"] = EMPTY_VALUE; + network["broadcast"] = UNKNOWN_VALUE; } void gateway(nlohmann::json& network) const override @@ -372,13 +372,13 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper void metricsV6(nlohmann::json& network) const override { - network["metric"] = EMPTY_VALUE; + network["metric"] = UNKNOWN_VALUE; } void dhcp(nlohmann::json& network) const override { auto fileData { Utils::getFileContent(WM_SYS_IF_FILE) }; - network["dhcp"] = EMPTY_VALUE; + network["dhcp"] = UNKNOWN_VALUE; const auto family { this->family() }; const auto ifName { this->name() }; @@ -449,7 +449,7 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper void mtu(nlohmann::json& network) const override { - network["mtu"] = EMPTY_VALUE; + network["mtu"] = UNKNOWN_VALUE; const auto mtuFileContent { Utils::getFileContent(std::string(WM_SYS_IFDATA_DIR) + this->name() + "/mtu") }; if (!mtuFileContent.empty()) @@ -518,7 +518,7 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper void state(nlohmann::json& network) const override { - network["state"] = EMPTY_VALUE; + network["state"] = UNKNOWN_VALUE; const std::string operationalState { Utils::getFileContent(std::string(WM_SYS_IFDATA_DIR) + this->name() + "/operstate") }; if (!operationalState.empty()) @@ -529,7 +529,7 @@ class NetworkLinuxInterface final : public INetworkInterfaceWrapper void MAC(nlohmann::json& network) const override { - network["mac"] = EMPTY_VALUE; + network["mac"] = UNKNOWN_VALUE; const std::string macContent { Utils::getFileContent(std::string(WM_SYS_IFDATA_DIR) + this->name() + "/address")}; if (!macContent.empty()) diff --git a/src/common/data_provider/src/network/networkWindowsWrapper.h b/src/common/data_provider/src/network/networkWindowsWrapper.h index 973cba4588..19008f0508 100644 --- a/src/common/data_provider/src/network/networkWindowsWrapper.h +++ b/src/common/data_provider/src/network/networkWindowsWrapper.h @@ -164,7 +164,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void broadcast(nlohmann::json& network) const override { - network["broadcast"] = EMPTY_VALUE; + network["broadcast"] = UNKNOWN_VALUE; const auto address { this->address() }; const auto netmask { this->netmask() }; @@ -180,7 +180,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void broadcastV6(nlohmann::json& network) const override { - network["broadcast"] = EMPTY_VALUE; + network["broadcast"] = UNKNOWN_VALUE; } void gateway(nlohmann::json& network) const override @@ -246,7 +246,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper if (retVal.empty()) { - network["gateway"] = EMPTY_VALUE; + network["gateway"] = UNKNOWN_VALUE; } else { @@ -258,7 +258,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void metrics(nlohmann::json& network) const override { - network["metric"] = EMPTY_VALUE; + network["metric"] = UNKNOWN_VALUE; if (Utils::isVistaOrLater()) { @@ -268,7 +268,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void metricsV6(nlohmann::json& network) const override { - network["metric"] = EMPTY_VALUE; + network["metric"] = UNKNOWN_VALUE; if (Utils::isVistaOrLater()) { @@ -278,7 +278,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void dhcp(nlohmann::json& network) const override { - network["dhcp"] = EMPTY_VALUE; + network["dhcp"] = UNKNOWN_VALUE; const auto family { this->adapterFamily() }; if (AF_INET == family) @@ -323,7 +323,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void state(nlohmann::json& network) const override { - network["state"] = EMPTY_VALUE; + network["state"] = UNKNOWN_VALUE; const auto opStatus { NETWORK_OPERATIONAL_STATUS.find(m_interfaceAddress->OperStatus) }; if (NETWORK_OPERATIONAL_STATUS.end() != opStatus) @@ -334,7 +334,7 @@ class NetworkWindowsInterface final : public INetworkInterfaceWrapper void MAC(nlohmann::json& network) const override { - network["mac"] = EMPTY_VALUE; + network["mac"] = UNKNOWN_VALUE; constexpr auto MAC_ADDRESS_LENGTH { 6 }; if (MAC_ADDRESS_LENGTH == m_interfaceAddress->PhysicalAddressLength) diff --git a/src/common/data_provider/src/packages/appxWindowsWrapper.h b/src/common/data_provider/src/packages/appxWindowsWrapper.h index c7da0206b0..2e48a88c31 100644 --- a/src/common/data_provider/src/packages/appxWindowsWrapper.h +++ b/src/common/data_provider/src/packages/appxWindowsWrapper.h @@ -57,12 +57,12 @@ class AppxWindowsWrapper final : public IPackageWrapper void groups(nlohmann::json& package) const override { - package["groups"] = EMPTY_VALUE; + package["groups"] = UNKNOWN_VALUE; } void description(nlohmann::json& package) const override { - package["description"] = EMPTY_VALUE; + package["description"] = UNKNOWN_VALUE; } void architecture(nlohmann::json& package) const override @@ -77,12 +77,12 @@ class AppxWindowsWrapper final : public IPackageWrapper void osPatch(nlohmann::json& package) const override { - package["os_patch"] = EMPTY_VALUE; + package["os_patch"] = UNKNOWN_VALUE; } void source(nlohmann::json& package) const override { - package["source"] = EMPTY_VALUE; + package["source"] = UNKNOWN_VALUE; } void location(nlohmann::json& package) const override @@ -92,7 +92,7 @@ class AppxWindowsWrapper final : public IPackageWrapper void priority(nlohmann::json& package) const override { - package["priority"] = EMPTY_VALUE; + package["priority"] = UNKNOWN_VALUE; } void size(nlohmann::json& package) const override diff --git a/src/common/data_provider/src/packages/brewWrapper.h b/src/common/data_provider/src/packages/brewWrapper.h index 2e01c0d783..fd258177ba 100644 --- a/src/common/data_provider/src/packages/brewWrapper.h +++ b/src/common/data_provider/src/packages/brewWrapper.h @@ -76,7 +76,7 @@ class BrewWrapper final : public IPackageWrapper void groups(nlohmann::json& package) const override { - package["groups"] = EMPTY_VALUE; + package["groups"] = UNKNOWN_VALUE; } void description(nlohmann::json& package) const override @@ -96,7 +96,7 @@ class BrewWrapper final : public IPackageWrapper void osPatch(nlohmann::json& package) const override { - package["os_patch"] = EMPTY_VALUE; + package["os_patch"] = UNKNOWN_VALUE; } void source(nlohmann::json& package) const override @@ -111,27 +111,27 @@ class BrewWrapper final : public IPackageWrapper void vendor(nlohmann::json& package) const override { - package["vendor"] = EMPTY_VALUE; + package["vendor"] = UNKNOWN_VALUE; } void priority(nlohmann::json& package) const override { - package["priority"] = EMPTY_VALUE; + package["priority"] = UNKNOWN_VALUE; } void size(nlohmann::json& package) const override { - package["size"] = EMPTY_VALUE; + package["size"] = UNKNOWN_VALUE; } void install_time(nlohmann::json& package) const override { - package["install_time"] = EMPTY_VALUE; + package["install_time"] = UNKNOWN_VALUE; } void multiarch(nlohmann::json& package) const override { - package["multiarch"] = EMPTY_VALUE; + package["multiarch"] = UNKNOWN_VALUE; } private: diff --git a/src/common/data_provider/src/packages/macportsWrapper.h b/src/common/data_provider/src/packages/macportsWrapper.h index 5cb931a13c..e849a340ff 100644 --- a/src/common/data_provider/src/packages/macportsWrapper.h +++ b/src/common/data_provider/src/packages/macportsWrapper.h @@ -58,11 +58,11 @@ class MacportsWrapper final : public IPackageWrapper } void groups(nlohmann::json& package) const override { - package["groups"] = EMPTY_VALUE; + package["groups"] = UNKNOWN_VALUE; } void description(nlohmann::json& package) const override { - package["description"] = EMPTY_VALUE; + package["description"] = UNKNOWN_VALUE; } void architecture(nlohmann::json& package) const override { @@ -74,11 +74,11 @@ class MacportsWrapper final : public IPackageWrapper } void osPatch(nlohmann::json& package) const override { - package["os_patch"] = EMPTY_VALUE; + package["os_patch"] = UNKNOWN_VALUE; } void source(nlohmann::json& package) const override { - package["source"] = EMPTY_VALUE; + package["source"] = UNKNOWN_VALUE; } void location(nlohmann::json& package) const override { @@ -86,17 +86,17 @@ class MacportsWrapper final : public IPackageWrapper } void vendor(nlohmann::json& package) const override { - package["vendor"] = EMPTY_VALUE; + package["vendor"] = UNKNOWN_VALUE; } void priority(nlohmann::json& package) const override { - package["priority"] = EMPTY_VALUE; + package["priority"] = UNKNOWN_VALUE; } void size(nlohmann::json& package) const override { - package["size"] = EMPTY_VALUE; + package["size"] = UNKNOWN_VALUE; } void install_time(nlohmann::json& package) const override @@ -106,7 +106,7 @@ class MacportsWrapper final : public IPackageWrapper void multiarch(nlohmann::json& package) const override { - package["multiarch"] = EMPTY_VALUE; + package["multiarch"] = UNKNOWN_VALUE; } private: void getPkgData(SQLiteLegacy::IStatement& stmt) diff --git a/src/common/data_provider/src/packages/packageLinuxParserHelper.h b/src/common/data_provider/src/packages/packageLinuxParserHelper.h index c83b0baa96..cb87980a12 100644 --- a/src/common/data_provider/src/packages/packageLinuxParserHelper.h +++ b/src/common/data_provider/src/packages/packageLinuxParserHelper.h @@ -69,15 +69,15 @@ namespace PackageLinuxHelper { ret["name"] = info.at("Package"); - nlohmann::json priority {EMPTY_VALUE}; - nlohmann::json groups {EMPTY_VALUE}; + nlohmann::json priority = UNKNOWN_VALUE; + nlohmann::json groups = UNKNOWN_VALUE; // The multiarch field won't have a default value - nlohmann::json multiarch; - nlohmann::json architecture {EMPTY_VALUE}; - nlohmann::json source {EMPTY_VALUE}; - nlohmann::json version {EMPTY_VALUE}; - nlohmann::json vendor {EMPTY_VALUE}; - nlohmann::json description {EMPTY_VALUE}; + nlohmann::json multiarch = UNKNOWN_VALUE; + nlohmann::json architecture = EMPTY_VALUE; + nlohmann::json source = UNKNOWN_VALUE; + nlohmann::json version = EMPTY_VALUE; + nlohmann::json vendor = UNKNOWN_VALUE; + nlohmann::json description = UNKNOWN_VALUE; int size { 0 }; auto it{info.find("Priority")}; @@ -153,7 +153,7 @@ namespace PackageLinuxHelper ret["format"] = "deb"; ret["location"] = EMPTY_VALUE; ret["vendor"] = vendor; - ret["install_time"] = EMPTY_VALUE; + ret["install_time"] = UNKNOWN_VALUE; ret["description"] = description; } @@ -166,9 +166,9 @@ namespace PackageLinuxHelper std::string name; std::string version; - nlohmann::json vendor { EMPTY_VALUE }; - nlohmann::json install_time { EMPTY_VALUE }; - nlohmann::json description { EMPTY_VALUE }; + nlohmann::json vendor = UNKNOWN_VALUE; + nlohmann::json install_time = UNKNOWN_VALUE; + nlohmann::json description = UNKNOWN_VALUE; int size { 0 }; bool hasName { false }; bool hasVersion { false }; @@ -260,10 +260,10 @@ namespace PackageLinuxHelper ret["source"] = "snapcraft"; ret["format"] = "snap"; - ret["priority"] = EMPTY_VALUE; - ret["multiarch"] = EMPTY_VALUE; + ret["priority"] = UNKNOWN_VALUE; + ret["multiarch"] = UNKNOWN_VALUE; ret["architecture"] = EMPTY_VALUE; - ret["groups"] = EMPTY_VALUE; + ret["groups"] = UNKNOWN_VALUE; return ret; } diff --git a/src/common/data_provider/src/packages/packageLinuxRpmParserHelper.h b/src/common/data_provider/src/packages/packageLinuxRpmParserHelper.h index e1e88ff92a..9a208c191b 100644 --- a/src/common/data_provider/src/packages/packageLinuxRpmParserHelper.h +++ b/src/common/data_provider/src/packages/packageLinuxRpmParserHelper.h @@ -51,11 +51,11 @@ namespace PackageLinuxHelper ret["location"] = EMPTY_VALUE; ret["groups"] = package.group; ret["version"] = version; - ret["priority"] = EMPTY_VALUE; + ret["priority"] = UNKNOWN_VALUE; ret["architecture"] = package.architecture; - ret["source"] = EMPTY_VALUE; + ret["source"] = UNKNOWN_VALUE; ret["format"] = "rpm"; - ret["vendor"] = package.vendor.empty() ? EMPTY_VALUE : package.vendor; + ret["vendor"] = package.vendor.empty() ? UNKNOWN_VALUE : package.vendor; ret["description"] = package.description; // The multiarch field won't have a default value } diff --git a/src/common/data_provider/src/packages/packageLinuxRpmParserHelperLegacy.h b/src/common/data_provider/src/packages/packageLinuxRpmParserHelperLegacy.h index f457256f17..cc8851e9f5 100644 --- a/src/common/data_provider/src/packages/packageLinuxRpmParserHelperLegacy.h +++ b/src/common/data_provider/src/packages/packageLinuxRpmParserHelperLegacy.h @@ -64,16 +64,16 @@ namespace PackageLinuxHelper ret["name"] = name; ret["size"] = size.empty() || size.compare(DEFAULT_VALUE) == 0 ? 0 : stoi(size); - ret["install_time"] = install_time.empty() || install_time.compare(DEFAULT_VALUE) == 0 ? EMPTY_VALUE : nlohmann::json(install_time); + ret["install_time"] = install_time.empty() || install_time.compare(DEFAULT_VALUE) == 0 ? UNKNOWN_VALUE : nlohmann::json(install_time); ret["location"] = EMPTY_VALUE; - ret["groups"] = groups.empty() || groups.compare(DEFAULT_VALUE) == 0 ? EMPTY_VALUE : nlohmann::json(groups); + ret["groups"] = groups.empty() || groups.compare(DEFAULT_VALUE) == 0 ? UNKNOWN_VALUE : nlohmann::json(groups); ret["version"] = version.empty() || version.compare(DEFAULT_VALUE) == 0 ? EMPTY_VALUE : nlohmann::json(version); - ret["priority"] = EMPTY_VALUE; + ret["priority"] = UNKNOWN_VALUE; ret["architecture"] = architecture.empty() || architecture.compare(DEFAULT_VALUE) == 0 ? EMPTY_VALUE : nlohmann::json(architecture); - ret["source"] = EMPTY_VALUE; + ret["source"] = UNKNOWN_VALUE; ret["format"] = "rpm"; - ret["vendor"] = vendor.empty() || vendor.compare(DEFAULT_VALUE) == 0 ? EMPTY_VALUE : nlohmann::json(vendor); - ret["description"] = description.empty() || description.compare(DEFAULT_VALUE) == 0 ? EMPTY_VALUE : nlohmann::json(description); + ret["vendor"] = vendor.empty() || vendor.compare(DEFAULT_VALUE) == 0 ? UNKNOWN_VALUE : nlohmann::json(vendor); + ret["description"] = description.empty() || description.compare(DEFAULT_VALUE) == 0 ? UNKNOWN_VALUE : nlohmann::json(description); // The multiarch field won't have a default value } } diff --git a/src/common/data_provider/src/packages/packagesNPM.hpp b/src/common/data_provider/src/packages/packagesNPM.hpp index a408a04ee2..2d8ee5db97 100644 --- a/src/common/data_provider/src/packages/packagesNPM.hpp +++ b/src/common/data_provider/src/packages/packagesNPM.hpp @@ -47,16 +47,16 @@ class NPM final const auto packageJson = TJsonReader::readJson(path); nlohmann::json packageInfo; - packageInfo["groups"] = EMPTY_VALUE; - packageInfo["description"] = EMPTY_VALUE; + packageInfo["groups"] = UNKNOWN_VALUE; + packageInfo["description"] = UNKNOWN_VALUE; packageInfo["architecture"] = EMPTY_VALUE; packageInfo["format"] = "npm"; - packageInfo["source"] = EMPTY_VALUE; + packageInfo["source"] = UNKNOWN_VALUE; packageInfo["location"] = path.string(); - packageInfo["priority"] = EMPTY_VALUE; - packageInfo["size"] = EMPTY_VALUE; - packageInfo["vendor"] = EMPTY_VALUE; - packageInfo["install_time"] = EMPTY_VALUE; + packageInfo["priority"] = UNKNOWN_VALUE; + packageInfo["size"] = UNKNOWN_VALUE; + packageInfo["vendor"] = UNKNOWN_VALUE; + packageInfo["install_time"] = UNKNOWN_VALUE; // The multiarch field won't have a default value // Iterate over fields diff --git a/src/common/data_provider/src/packages/packagesPYPI.hpp b/src/common/data_provider/src/packages/packagesPYPI.hpp index cc0ab6c266..65b551bfe9 100644 --- a/src/common/data_provider/src/packages/packagesPYPI.hpp +++ b/src/common/data_provider/src/packages/packagesPYPI.hpp @@ -38,16 +38,16 @@ class PYPI final : public TFileSystem, public TFileIO // Parse the METADATA file nlohmann::json packageInfo; - packageInfo["groups"] = EMPTY_VALUE; - packageInfo["description"] = EMPTY_VALUE; + packageInfo["groups"] = UNKNOWN_VALUE; + packageInfo["description"] = UNKNOWN_VALUE; packageInfo["architecture"] = EMPTY_VALUE; packageInfo["format"] = "pypi"; - packageInfo["source"] = EMPTY_VALUE; + packageInfo["source"] = UNKNOWN_VALUE; packageInfo["location"] = path.string(); - packageInfo["priority"] = EMPTY_VALUE; - packageInfo["size"] = EMPTY_VALUE; - packageInfo["vendor"] = EMPTY_VALUE; - packageInfo["install_time"] = EMPTY_VALUE; + packageInfo["priority"] = UNKNOWN_VALUE; + packageInfo["size"] = UNKNOWN_VALUE; + packageInfo["vendor"] = UNKNOWN_VALUE; + packageInfo["install_time"] = UNKNOWN_VALUE; // The multiarch field won't have a default value TFileIO::readLineByLine(path, diff --git a/src/common/data_provider/src/packages/pkgWrapper.h b/src/common/data_provider/src/packages/pkgWrapper.h index 442dfd44b3..17c7e1772d 100644 --- a/src/common/data_provider/src/packages/pkgWrapper.h +++ b/src/common/data_provider/src/packages/pkgWrapper.h @@ -80,7 +80,7 @@ class PKGWrapper final : public IPackageWrapper } void osPatch(nlohmann::json& package) const override { - package["os_patch"] = EMPTY_VALUE; + package["os_patch"] = UNKNOWN_VALUE; } void source(nlohmann::json& package) const override { @@ -97,12 +97,12 @@ class PKGWrapper final : public IPackageWrapper void priority(nlohmann::json& package) const override { - package["priority"] = EMPTY_VALUE; + package["priority"] = UNKNOWN_VALUE; } void size(nlohmann::json& package) const override { - package["size"] = EMPTY_VALUE; + package["size"] = UNKNOWN_VALUE; } void install_time(nlohmann::json& package) const override @@ -112,7 +112,7 @@ class PKGWrapper final : public IPackageWrapper void multiarch(nlohmann::json& package) const override { - package["multiarch"] = EMPTY_VALUE; + package["multiarch"] = UNKNOWN_VALUE; } private: diff --git a/src/common/data_provider/src/ports/portBSDWrapper.h b/src/common/data_provider/src/ports/portBSDWrapper.h index cf258fce16..3299afa387 100644 --- a/src/common/data_provider/src/ports/portBSDWrapper.h +++ b/src/common/data_provider/src/ports/portBSDWrapper.h @@ -135,12 +135,12 @@ class BSDPortWrapper final : public IPortWrapper void txQueue(nlohmann::json& port) const override { - port["tx_queue"] = EMPTY_VALUE; + port["tx_queue"] = UNKNOWN_VALUE; } void rxQueue(nlohmann::json& port) const override { - port["rx_queue"] = EMPTY_VALUE; + port["rx_queue"] = UNKNOWN_VALUE; } void inode(nlohmann::json& port) const override @@ -150,7 +150,7 @@ class BSDPortWrapper final : public IPortWrapper void state(nlohmann::json& port) const override { - port["state"] = EMPTY_VALUE; + port["state"] = UNKNOWN_VALUE; const auto itProtocol { PORTS_TYPE.find(m_spSocketInfo->psi.soi_kind) }; diff --git a/src/common/data_provider/src/ports/portLinuxWrapper.h b/src/common/data_provider/src/ports/portLinuxWrapper.h index 2c8301842b..b954591a2b 100644 --- a/src/common/data_provider/src/ports/portLinuxWrapper.h +++ b/src/common/data_provider/src/ports/portLinuxWrapper.h @@ -175,7 +175,7 @@ class LinuxPortWrapper final : public IPortWrapper void remoteIP(nlohmann::json& port) const override { - port["remote_ip"] = EMPTY_VALUE; + port["remote_ip"] = UNKNOWN_VALUE; if (m_remoteAddresses.size() == AddressField::ADDRESS_FIELD_SIZE) { @@ -203,7 +203,7 @@ class LinuxPortWrapper final : public IPortWrapper } else { - port["remote_port"] = EMPTY_VALUE; + port["remote_port"] = UNKNOWN_VALUE; } } @@ -220,7 +220,7 @@ class LinuxPortWrapper final : public IPortWrapper } else { - port["tx_queue"] = EMPTY_VALUE; + port["tx_queue"] = UNKNOWN_VALUE; } } @@ -237,7 +237,7 @@ class LinuxPortWrapper final : public IPortWrapper } else { - port["rx_queue"] = EMPTY_VALUE; + port["rx_queue"] = UNKNOWN_VALUE; } } @@ -258,7 +258,7 @@ class LinuxPortWrapper final : public IPortWrapper void state(nlohmann::json& port) const override { - port["state"] = EMPTY_VALUE; + port["state"] = UNKNOWN_VALUE; const auto it { PROTOCOL_TYPE.find(m_type) }; if (PROTOCOL_TYPE.end() != it && TCP == it->second) @@ -279,12 +279,12 @@ class LinuxPortWrapper final : public IPortWrapper void processName(nlohmann::json& port) const override { - port["process"] = EMPTY_VALUE; + port["process"] = UNKNOWN_VALUE; } void pid(nlohmann::json& port) const override { - port["pid"] = EMPTY_VALUE; + port["pid"] = UNKNOWN_VALUE; } }; diff --git a/src/common/data_provider/src/ports/portWindowsWrapper.h b/src/common/data_provider/src/ports/portWindowsWrapper.h index 63a69438b4..a332967707 100644 --- a/src/common/data_provider/src/ports/portWindowsWrapper.h +++ b/src/common/data_provider/src/ports/portWindowsWrapper.h @@ -161,12 +161,12 @@ class WindowsPortWrapper final : public IPortWrapper void txQueue(nlohmann::json& port) const override { - port["tx_queue"] = EMPTY_VALUE; + port["tx_queue"] = UNKNOWN_VALUE; } void rxQueue(nlohmann::json& port) const override { - port["rx_queue"] = EMPTY_VALUE; + port["rx_queue"] = UNKNOWN_VALUE; } void inode(nlohmann::json& port) const override @@ -176,7 +176,7 @@ class WindowsPortWrapper final : public IPortWrapper void state(nlohmann::json& port) const override { - port["state"] = EMPTY_VALUE; + port["state"] = UNKNOWN_VALUE; const auto itState { STATE_TYPE.find(m_state) }; if (STATE_TYPE.end() != itState) diff --git a/src/common/data_provider/src/sharedDefs.h b/src/common/data_provider/src/sharedDefs.h index 8829193cb1..515224298d 100644 --- a/src/common/data_provider/src/sharedDefs.h +++ b/src/common/data_provider/src/sharedDefs.h @@ -33,6 +33,7 @@ constexpr auto RPM_PATH {"/var/lib/rpm/"}; constexpr auto SNAP_PATH {"/var/lib/snapd"}; +constexpr auto UNKNOWN_VALUE {nullptr}; constexpr auto EMPTY_VALUE {""}; constexpr auto MAC_ADDRESS_COUNT_SEGMENTS { diff --git a/src/common/data_provider/src/sysInfoLinux.cpp b/src/common/data_provider/src/sysInfoLinux.cpp index effdfc83e0..9b182be700 100644 --- a/src/common/data_provider/src/sysInfoLinux.cpp +++ b/src/common/data_provider/src/sysInfoLinux.cpp @@ -152,7 +152,7 @@ static void getSerialNumber(nlohmann::json& info) static void getCpuName(nlohmann::json& info) { - info["cpu_name"] = EMPTY_VALUE; + info["cpu_name"] = UNKNOWN_VALUE; std::map systemInfo; getSystemInfo(WM_SYS_CPU_DIR, ":", systemInfo); const auto& it { systemInfo.find("model name") }; @@ -165,7 +165,7 @@ static void getCpuName(nlohmann::json& info) static void getCpuCores(nlohmann::json& info) { - info["cpu_cores"] = EMPTY_VALUE; + info["cpu_cores"] = UNKNOWN_VALUE; std::map systemInfo; getSystemInfo(WM_SYS_CPU_DIR, ":", systemInfo); const auto& it { systemInfo.find("processor") }; @@ -178,7 +178,7 @@ static void getCpuCores(nlohmann::json& info) static void getCpuMHz(nlohmann::json& info) { - info["cpu_mhz"] = EMPTY_VALUE; + info["cpu_mhz"] = UNKNOWN_VALUE; int retVal { 0 }; std::map systemInfo; getSystemInfo(WM_SYS_CPU_DIR, ":", systemInfo); @@ -347,7 +347,7 @@ nlohmann::json SysInfo::getOsInfo() const { ret["os_name"] = "Linux"; ret["os_platform"] = "linux"; - ret["os_version"] = EMPTY_VALUE; + ret["os_version"] = UNKNOWN_VALUE; } if (uname(&uts) >= 0) diff --git a/src/common/data_provider/src/sysInfoMac.cpp b/src/common/data_provider/src/sysInfoMac.cpp index dc5a82b735..a404dd0bed 100644 --- a/src/common/data_provider/src/sysInfoMac.cpp +++ b/src/common/data_provider/src/sysInfoMac.cpp @@ -65,7 +65,7 @@ static nlohmann::json getProcessInfo(const ProcessTaskInfo& taskInfo, const pid_ jsProcessInfo["pid"] = std::to_string(pid); jsProcessInfo["name"] = taskInfo.pbsd.pbi_name; - jsProcessInfo["state"] = EMPTY_VALUE; + jsProcessInfo["state"] = UNKNOWN_VALUE; jsProcessInfo["ppid"] = taskInfo.pbsd.pbi_ppid; const auto eUser { getpwuid(taskInfo.pbsd.pbi_uid) }; diff --git a/src/common/data_provider/src/sysInfoUnix.cpp b/src/common/data_provider/src/sysInfoUnix.cpp index 689b7c0ee5..9b81009077 100644 --- a/src/common/data_provider/src/sysInfoUnix.cpp +++ b/src/common/data_provider/src/sysInfoUnix.cpp @@ -20,7 +20,7 @@ static void getOsInfoFromUname(nlohmann::json& info) { info["os_name"] = "Unix"; info["os_platform"] = "Unix"; - info["os_version"] = EMPTY_VALUE; + info["os_version"] = UNKNOWN_VALUE; } diff --git a/src/common/data_provider/src/sysInfoWin.cpp b/src/common/data_provider/src/sysInfoWin.cpp index fec4af5620..cda3e8a9cb 100644 --- a/src/common/data_provider/src/sysInfoWin.cpp +++ b/src/common/data_provider/src/sysInfoWin.cpp @@ -376,7 +376,7 @@ static void getPackagesFromReg(const HKEY key, const std::string& subKey, std::f packageJson["version"] = value; } - packageJson["vendor"] = EMPTY_VALUE; + packageJson["vendor"] = UNKNOWN_VALUE; if (packageReg.string("Publisher", value)) { packageJson["vendor"] = value; @@ -415,11 +415,11 @@ static void getPackagesFromReg(const HKEY key, const std::string& subKey, std::f packageJson["architecture"] = "x86_64"; } - packageJson["description"] = EMPTY_VALUE; - packageJson["groups"] = EMPTY_VALUE; - packageJson["priority"] = EMPTY_VALUE; - packageJson["size"] = EMPTY_VALUE; - packageJson["source"] = EMPTY_VALUE; + packageJson["description"] = UNKNOWN_VALUE; + packageJson["groups"] = UNKNOWN_VALUE; + packageJson["priority"] = UNKNOWN_VALUE; + packageJson["size"] = UNKNOWN_VALUE; + packageJson["source"] = UNKNOWN_VALUE; packageJson["format"] = "win"; returnCallback(packageJson); diff --git a/src/common/data_provider/tests/sysInfoPackageLinuxParserRpm/sysInfoPackageLinuxParserRPM_test.cpp b/src/common/data_provider/tests/sysInfoPackageLinuxParserRpm/sysInfoPackageLinuxParserRPM_test.cpp index a75df6442e..6831492173 100644 --- a/src/common/data_provider/tests/sysInfoPackageLinuxParserRpm/sysInfoPackageLinuxParserRPM_test.cpp +++ b/src/common/data_provider/tests/sysInfoPackageLinuxParserRpm/sysInfoPackageLinuxParserRPM_test.cpp @@ -187,7 +187,7 @@ TEST(SysInfoPackageLinuxParserRPM_test, rpmFromBerkleyDB) CallbackMock wrapper; auto expectedPackage1 = - R"({"architecture":"amd64","description":"The Open Source Security Platform","format":"rpm","groups":"test","install_time":"5","name":"Wazuh","size":321,"vendor":"The Wazuh Team","version":"123:4.4-1","location":"","priority":"","source":""})"_json; + R"({"architecture":"amd64","description":"The Open Source Security Platform","format":"rpm","groups":"test","install_time":"5","name":"Wazuh","size":321,"vendor":"The Wazuh Team","version":"123:4.4-1","location":"","priority":null,"source":null})"_json; auto utils_mock { std::make_unique() }; auto libdb_mock { std::make_unique() }; @@ -345,7 +345,7 @@ TEST(SysInfoPackageLinuxParserRPM_test, rpmFromLibRPM) CallbackMock wrapper; auto expectedPackage1 = - R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":"","source":""})"_json; + R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":null,"source":null})"_json; auto utils_mock { std::make_unique() }; auto rpm_mock { std::make_unique() }; @@ -402,9 +402,9 @@ TEST(SysInfoPackageLinuxParserRPM_test, rpmFallbackFromLibRPM) CallbackMock wrapper; auto expectedPackage1 = - R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":"","source":""})"_json; + R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":null,"source":null})"_json; auto expectedPackage2 = - R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":"","priority":"","source":""})"_json; + R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":"","priority":null,"source":null})"_json; auto utils_mock { std::make_unique() }; auto rpm_mock { std::make_unique() }; @@ -430,9 +430,9 @@ TEST(SysInfoPackageLinuxParserRPM_test, rpmFallbackFromBerkleyDBConfigError) CallbackMock wrapper; auto expectedPackage1 = - R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":"","source":""})"_json; + R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":null,"source":null})"_json; auto expectedPackage2 = - R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":"","priority":"","source":""})"_json; + R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":"","priority":null,"source":null})"_json; auto utils_mock { std::make_unique() }; auto libdb_mock { std::make_unique() }; @@ -459,9 +459,9 @@ TEST(SysInfoPackageLinuxParserRPM_test, rpmFallbackFromBerkleyDBOpenError) CallbackMock wrapper; auto expectedPackage1 = - R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":"","source":""})"_json; + R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":null,"source":null})"_json; auto expectedPackage2 = - R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":"","priority":"","source":""})"_json; + R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":"","priority":null,"source":null})"_json; auto utils_mock { std::make_unique() }; auto libdb_mock { std::make_unique() }; @@ -497,9 +497,9 @@ TEST(SysInfoPackageLinuxParserRPM_test, rpmFallbackFromBerkleyDBCursorError) CallbackMock wrapper; auto expectedPackage1 = - R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":"","source":""})"_json; + R"({"name":"1","architecture":"2","description":"3","size":4,"version":"5:7-6","vendor":"8","install_time":"9","groups":"10","format":"rpm","location":"","priority":null,"source":null})"_json; auto expectedPackage2 = - R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":"","priority":"","source":""})"_json; + R"({"name":"11","architecture":"12","description":"13","size":14,"version":"15:17-16","vendor":"18","install_time":"19","groups":"20","format":"rpm","location":"","priority":null,"source":null})"_json; auto utils_mock { std::make_unique() }; auto libdb_mock { std::make_unique() }; diff --git a/src/common/data_provider/tests/sysInfoPackagesLinuxHelper/sysInfoPackagesLinuxHelper_test.cpp b/src/common/data_provider/tests/sysInfoPackagesLinuxHelper/sysInfoPackagesLinuxHelper_test.cpp index f7a0f1e3cc..5eda2de114 100644 --- a/src/common/data_provider/tests/sysInfoPackagesLinuxHelper/sysInfoPackagesLinuxHelper_test.cpp +++ b/src/common/data_provider/tests/sysInfoPackagesLinuxHelper/sysInfoPackagesLinuxHelper_test.cpp @@ -99,13 +99,13 @@ TEST_F(SysInfoPackagesLinuxHelperTest, parseRpmInformationUnknownInEmpty) EXPECT_FALSE(jsPackageInfo.empty()); EXPECT_EQ("curl", jsPackageInfo["name"]); EXPECT_EQ(0, jsPackageInfo["size"]); - EXPECT_EQ(EMPTY_VALUE, jsPackageInfo["install_time"]); - EXPECT_EQ(EMPTY_VALUE, jsPackageInfo["groups"]); + EXPECT_EQ(UNKNOWN_VALUE, jsPackageInfo["install_time"]); + EXPECT_EQ(UNKNOWN_VALUE, jsPackageInfo["groups"]); EXPECT_EQ(EMPTY_VALUE, jsPackageInfo["version"]); EXPECT_EQ(EMPTY_VALUE, jsPackageInfo["architecture"]); EXPECT_EQ("rpm", jsPackageInfo["format"]); - EXPECT_EQ(EMPTY_VALUE, jsPackageInfo["vendor"]); - EXPECT_EQ(EMPTY_VALUE, jsPackageInfo["description"]); + EXPECT_EQ(UNKNOWN_VALUE, jsPackageInfo["vendor"]); + EXPECT_EQ(UNKNOWN_VALUE, jsPackageInfo["description"]); } @@ -370,9 +370,9 @@ TEST_F(SysInfoPackagesLinuxHelperTest, parseSnapCorrectMapping) EXPECT_EQ("gnome-3-38-2004", jsPackageInfo["name"]); EXPECT_EQ(363151360, jsPackageInfo["size"]); EXPECT_EQ("2022/11/23 20:33:59", jsPackageInfo["install_time"]); - EXPECT_EQ("", jsPackageInfo["groups"]); + EXPECT_TRUE(jsPackageInfo["groups"].is_null()); EXPECT_EQ("0+git.6f39565", jsPackageInfo["version"]); - EXPECT_EQ("", jsPackageInfo["groups"]); + EXPECT_TRUE(jsPackageInfo["groups"].is_null()); EXPECT_EQ("snap", jsPackageInfo["format"]); EXPECT_EQ("Canonical", jsPackageInfo["vendor"]); EXPECT_EQ("Shared GNOME 3.38 Ubuntu stack", jsPackageInfo["description"]); diff --git a/src/common/data_provider/tests/sysInfoPackagesMAC/pkgWrapper_test.cpp b/src/common/data_provider/tests/sysInfoPackagesMAC/pkgWrapper_test.cpp index 984dd264f1..accdba42fd 100644 --- a/src/common/data_provider/tests/sysInfoPackagesMAC/pkgWrapper_test.cpp +++ b/src/common/data_provider/tests/sysInfoPackagesMAC/pkgWrapper_test.cpp @@ -49,7 +49,7 @@ TEST_F(PKGWrapperTest, LongVersion) wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -57,13 +57,13 @@ TEST_F(PKGWrapperTest, LongVersion) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "operasoftware"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); + EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], EMPTY_VALUE); + EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); } TEST_F(PKGWrapperTest, ShortVersion) @@ -93,7 +93,7 @@ TEST_F(PKGWrapperTest, ShortVersion) wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -101,13 +101,13 @@ TEST_F(PKGWrapperTest, ShortVersion) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "operasoftware"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); + EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], EMPTY_VALUE); + EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); } TEST_F(PKGWrapperTest, NoName) @@ -137,7 +137,7 @@ TEST_F(PKGWrapperTest, NoName) wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -145,13 +145,13 @@ TEST_F(PKGWrapperTest, NoName) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "operasoftware"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); + EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], EMPTY_VALUE); + EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); } TEST_F(PKGWrapperTest, NoVersion) @@ -181,7 +181,7 @@ TEST_F(PKGWrapperTest, NoVersion) wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -189,13 +189,13 @@ TEST_F(PKGWrapperTest, NoVersion) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "operasoftware"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); + EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], EMPTY_VALUE); + EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); } TEST_F(PKGWrapperTest, NoGroups) @@ -225,7 +225,7 @@ TEST_F(PKGWrapperTest, NoGroups) wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -233,13 +233,13 @@ TEST_F(PKGWrapperTest, NoGroups) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "operasoftware"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); + EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], EMPTY_VALUE); + EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); } TEST_F(PKGWrapperTest, NoDescription) @@ -269,7 +269,7 @@ TEST_F(PKGWrapperTest, NoDescription) wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -277,13 +277,13 @@ TEST_F(PKGWrapperTest, NoDescription) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], EMPTY_VALUE); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); + EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], EMPTY_VALUE); + EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); } TEST_F(PKGWrapperTest, NoVendor) @@ -313,7 +313,7 @@ TEST_F(PKGWrapperTest, NoVendor) wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "utilities"); wrapper->location(packageJson); @@ -321,13 +321,13 @@ TEST_F(PKGWrapperTest, NoVendor) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], EMPTY_VALUE); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); + EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], EMPTY_VALUE); + EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], EMPTY_VALUE); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); } TEST_F(PKGWrapperTest, pkgVersionXML) @@ -357,7 +357,7 @@ TEST_F(PKGWrapperTest, pkgVersionXML) wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "receipts"); wrapper->location(packageJson); @@ -365,13 +365,13 @@ TEST_F(PKGWrapperTest, pkgVersionXML) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "wazuh"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); + EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], EMPTY_VALUE); + EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], "2024-11-07T08:58:38Z"); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); } TEST_F(PKGWrapperTest, pkgVersionBin) @@ -401,7 +401,7 @@ TEST_F(PKGWrapperTest, pkgVersionBin) wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "receipts"); wrapper->location(packageJson); @@ -409,13 +409,13 @@ TEST_F(PKGWrapperTest, pkgVersionBin) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "zoom"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); + EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], EMPTY_VALUE); + EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], "2024-11-08T11:44:04Z"); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); } TEST_F(PKGWrapperTest, pkgVersionLong) @@ -445,7 +445,7 @@ TEST_F(PKGWrapperTest, pkgVersionLong) wrapper->format(packageJson); EXPECT_EQ(packageJson["format"], "pkg"); wrapper->osPatch(packageJson); - EXPECT_EQ(packageJson["os_patch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["os_patch"], UNKNOWN_VALUE); wrapper->source(packageJson); EXPECT_EQ(packageJson["source"], "receipts"); wrapper->location(packageJson); @@ -453,11 +453,11 @@ TEST_F(PKGWrapperTest, pkgVersionLong) wrapper->vendor(packageJson); EXPECT_EQ(packageJson["vendor"], "R-project"); wrapper->priority(packageJson); - EXPECT_EQ(packageJson["priority"], EMPTY_VALUE); + EXPECT_EQ(packageJson["priority"], UNKNOWN_VALUE); wrapper->size(packageJson); - EXPECT_EQ(packageJson["size"], EMPTY_VALUE); + EXPECT_EQ(packageJson["size"], UNKNOWN_VALUE); wrapper->install_time(packageJson); EXPECT_EQ(packageJson["install_time"], "2024-11-13T10:59:10Z"); wrapper->multiarch(packageJson); - EXPECT_EQ(packageJson["multiarch"], EMPTY_VALUE); + EXPECT_EQ(packageJson["multiarch"], UNKNOWN_VALUE); } diff --git a/src/common/dbsync/src/sqlite/isqlite_wrapper.h b/src/common/dbsync/src/sqlite/isqlite_wrapper.h index 72271f881e..31651563e8 100644 --- a/src/common/dbsync/src/sqlite/isqlite_wrapper.h +++ b/src/common/dbsync/src/sqlite/isqlite_wrapper.h @@ -81,6 +81,7 @@ namespace SQLiteLegacy virtual void bind(const int32_t index, const int64_t value) = 0; virtual void bind(const int32_t index, const std::string& value) = 0; virtual void bind(const int32_t index, const double_t value) = 0; + virtual void bind(const int32_t index) = 0; virtual int columnsCount() const = 0; virtual std::string expand() = 0; diff --git a/src/common/dbsync/src/sqlite/sqlite_dbengine.cpp b/src/common/dbsync/src/sqlite/sqlite_dbengine.cpp index 3b1aede530..cd2f0ffc75 100644 --- a/src/common/dbsync/src/sqlite/sqlite_dbengine.cpp +++ b/src/common/dbsync/src/sqlite/sqlite_dbengine.cpp @@ -804,13 +804,24 @@ bool SQLiteDBEngine::bindJsonData(const std::shared_ptr(cd) }; const auto name { std::get(cd) }; + const auto isPrimaryKey { std::get(cd) }; const auto& it { valueType.find(name) }; if (valueType.end() != it) { const auto& jsData { *it }; - if (ColumnType::BigInt == type) + if (jsData.is_null()) { + if(!isPrimaryKey) + { + stmt->bind(cid); + } + else + { + throw dbengine_error { INVALID_DATA_BIND }; + } + } + else if (ColumnType::BigInt == type) { int64_t value { @@ -994,25 +1005,31 @@ void SQLiteDBEngine::getTableData(std::shared_ptrconst const std::string& fieldName, Row& row) { + if (!stmt->column(index)->hasValue()) + { + row[fieldName] = std::make_tuple(type, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt); + return; + } + if (ColumnType::BigInt == type) { - row[fieldName] = std::make_tuple(type, std::string(), 0, stmt->column(index)->value(int64_t{}), 0, 0); + row[fieldName] = std::make_tuple(type, std::nullopt, std::nullopt, stmt->column(index)->value(int64_t{}), std::nullopt, std::nullopt); } else if (ColumnType::UnsignedBigInt == type) { - row[fieldName] = std::make_tuple(type, std::string(), 0, 0, stmt->column(index)->value(int64_t{}), 0); + row[fieldName] = std::make_tuple(type, std::nullopt, std::nullopt, std::nullopt, stmt->column(index)->value(uint64_t{}), std::nullopt); } else if (ColumnType::Integer == type) { - row[fieldName] = std::make_tuple(type, std::string(), stmt->column(index)->value(int32_t{}), 0, 0, 0); + row[fieldName] = std::make_tuple(type, std::nullopt, stmt->column(index)->value(int32_t{}), std::nullopt, std::nullopt, std::nullopt); } else if (ColumnType::Text == type) { - row[fieldName] = std::make_tuple(type, stmt->column(index)->value(std::string{}), 0, 0, 0, 0); + row[fieldName] = std::make_tuple(type, stmt->column(index)->value(std::string{}), std::nullopt, std::nullopt, std::nullopt, std::nullopt); } else if (ColumnType::Double == type) { - row[fieldName] = std::make_tuple(type, std::string(), 0, 0, 0, stmt->column(index)->value(double_t{})); + row[fieldName] = std::make_tuple(type, std::nullopt, std::nullopt, std::nullopt, std::nullopt, stmt->column(index)->value(double_t{})); } else { @@ -1238,27 +1255,62 @@ void SQLiteDBEngine::bindFieldData(const std::shared_ptr(fieldData) }; - stmt->bind(index, value); + if (value.has_value()) + { + stmt->bind(index, value.value()); + } + else + { + stmt->bind(index); + } } else if (ColumnType::UnsignedBigInt == type) { const auto value { std::get(fieldData) }; - stmt->bind(index, value); + if (value.has_value()) + { + stmt->bind(index, value.value()); + } + else + { + stmt->bind(index); + } } else if (ColumnType::Integer == type) { const auto value { std::get(fieldData) }; - stmt->bind(index, value); + if (value.has_value()) + { + stmt->bind(index, value.value()); + } + else + { + stmt->bind(index); + } } else if (ColumnType::Text == type) { const auto value { std::get(fieldData) }; - stmt->bind(index, value); + if (value.has_value()) + { + stmt->bind(index, value.value()); + } + else + { + stmt->bind(index); + } } else if (ColumnType::Double == type) { const auto value { std::get(fieldData) }; - stmt->bind(index, value); + if (value.has_value()) + { + stmt->bind(index, value.value()); + } + else + { + stmt->bind(index); + } } else { @@ -1266,7 +1318,6 @@ void SQLiteDBEngine::bindFieldData(const std::shared_ptr(value.second); + const auto& optValue = std::get(value.second); + object[value.first] = optValue.has_value() ? nlohmann::json(optValue.value()) : nlohmann::json(nullptr); } else if (ColumnType::UnsignedBigInt == rowType) { - object[value.first] = std::get(value.second); + const auto& optValue = std::get(value.second); + object[value.first] = optValue.has_value() ? nlohmann::json(optValue.value()) : nlohmann::json(nullptr); } else if (ColumnType::Integer == rowType) { - object[value.first] = std::get(value.second); + const auto& optValue = std::get(value.second); + object[value.first] = optValue.has_value() ? nlohmann::json(optValue.value()) : nlohmann::json(nullptr); } else if (ColumnType::Text == rowType) { - object[value.first] = std::get(value.second); + const auto& optValue = std::get(value.second); + object[value.first] = optValue.has_value() ? nlohmann::json(optValue.value()) : nlohmann::json(nullptr); } else if (ColumnType::Double == rowType) { - object[value.first] = std::get(value.second); + const auto& optValue = std::get(value.second); + object[value.first] = optValue.has_value() ? nlohmann::json(optValue.value()) : nlohmann::json(nullptr); } else { @@ -1953,30 +2009,42 @@ void SQLiteDBEngine::getFieldValueFromTuple(const Field& value, if (ColumnType::BigInt == rowType) { - resultValue.append(std::to_string(std::get(value.second))); + const auto& optValue = std::get(value.second); + resultValue.append(optValue.has_value() ? std::to_string(optValue.value()) : "null"); } else if (ColumnType::UnsignedBigInt == rowType) { - resultValue.append(std::to_string(std::get(value.second))); + const auto& optValue = std::get(value.second); + resultValue.append(optValue.has_value() ? std::to_string(optValue.value()) : "null"); } else if (ColumnType::Integer == rowType) { - resultValue.append(std::to_string(std::get(value.second))); + const auto& optValue = std::get(value.second); + resultValue.append(optValue.has_value() ? std::to_string(optValue.value()) : "null"); } else if (ColumnType::Text == rowType) { - if (quotationMarks) + const auto& optValue = std::get(value.second); + if (optValue.has_value()) { - resultValue.append("'" + std::get(value.second) + "'"); + if (quotationMarks) + { + resultValue.append("'" + optValue.value() + "'"); + } + else + { + resultValue.append(optValue.value()); + } } else { - resultValue.append(std::get(value.second)); + resultValue.append("null"); } } else if (ColumnType::Double == rowType) { - resultValue.append(std::to_string(std::get(value.second))); + const auto& optValue = std::get(value.second); + resultValue.append(optValue.has_value() ? std::to_string(optValue.value()) : "null"); } else { diff --git a/src/common/dbsync/src/sqlite/sqlite_dbengine.h b/src/common/dbsync/src/sqlite/sqlite_dbengine.h index 8dddf8c703..8e8a74b3b1 100644 --- a/src/common/dbsync/src/sqlite/sqlite_dbengine.h +++ b/src/common/dbsync/src/sqlite/sqlite_dbengine.h @@ -83,8 +83,12 @@ using ColumnData = using TableColumns = std::vector; -using TableField = - std::tuple; +using TableField = std::tuple, // Text or null + std::optional, // Integer or null + std::optional, // BigInt or null + std::optional, // UnsignedBigInt or null + std::optional>; // Double or null using Row = std::map; diff --git a/src/common/dbsync/src/sqlite/sqlite_wrapper.cpp b/src/common/dbsync/src/sqlite/sqlite_wrapper.cpp index d4555fe88a..07a4b34441 100644 --- a/src/common/dbsync/src/sqlite/sqlite_wrapper.cpp +++ b/src/common/dbsync/src/sqlite/sqlite_wrapper.cpp @@ -260,6 +260,12 @@ void Statement::bind(const int32_t index, const double_t value) checkSqliteResult(result, sqlite3_errmsg(m_connection->db().get())); ++m_bindParametersIndex; } +void Statement::bind(const int32_t index) +{ + const auto result{ sqlite3_bind_null(m_stmt.get(), index) }; + checkSqliteResult(result, sqlite3_errmsg(m_connection->db().get())); + ++m_bindParametersIndex; +} // LCOV_EXCL_START std::string Statement::expand() diff --git a/src/common/dbsync/src/sqlite/sqlite_wrapper.h b/src/common/dbsync/src/sqlite/sqlite_wrapper.h index 0937c19690..be6a8508d1 100644 --- a/src/common/dbsync/src/sqlite/sqlite_wrapper.h +++ b/src/common/dbsync/src/sqlite/sqlite_wrapper.h @@ -85,6 +85,7 @@ namespace SQLiteLegacy void bind(const int32_t index, const int64_t value) override; void bind(const int32_t index, const std::string& value) override; void bind(const int32_t index, const double_t value) override; + void bind(const int32_t index) override; int columnsCount() const override; std::string expand() override; diff --git a/src/common/dbsync/tests/dbengine/dbengine_test.cpp b/src/common/dbsync/tests/dbengine/dbengine_test.cpp index 48a22b7824..a19d68a138 100644 --- a/src/common/dbsync/tests/dbengine/dbengine_test.cpp +++ b/src/common/dbsync/tests/dbengine/dbengine_test.cpp @@ -607,12 +607,14 @@ TEST_F(DBEngineTest, GetRowsToBeDeletedByStatusField) .WillOnce(Return(SQLITE_ROW)) .WillOnce(Return(SQLITE_DONE)); - auto mockColumn_9 { std::make_unique() }; - EXPECT_CALL(*mockColumn_9, value(An())) - .WillOnce(Return(1)); + auto mockColumn_9 = std::make_unique(); + EXPECT_CALL(*mockColumn_9, hasValue()).WillOnce(Return(true)); + auto mockColumn_10 = std::make_unique(); + EXPECT_CALL(*mockColumn_10, value(An())).WillOnce(Return(1)); EXPECT_CALL(*mockStatement_3, column(0)) - .WillOnce(Return(ByMove(std::move(mockColumn_9)))); + .WillOnce(Return(ByMove(std::move(mockColumn_9)))) + .WillOnce(Return(ByMove(std::move(mockColumn_10)))); EXPECT_CALL(*mockFactory, createStatement(_, "SELECT PID FROM dummy WHERE db_status_field_dm=0;")) diff --git a/src/common/dbsync/tests/mocks/sqlitewrapper_mock.h b/src/common/dbsync/tests/mocks/sqlitewrapper_mock.h index f78ac3d2f1..9e61c68074 100644 --- a/src/common/dbsync/tests/mocks/sqlitewrapper_mock.h +++ b/src/common/dbsync/tests/mocks/sqlitewrapper_mock.h @@ -119,7 +119,10 @@ class MockStatement : public SQLiteLegacy::IStatement bind, (const int32_t index, const double_t value), (override)); - + MOCK_METHOD(void, + bind, + (const int32_t index), + (override)); MOCK_METHOD(std::string, expand, (), diff --git a/src/modules/inventory/src/inventoryImp.cpp b/src/modules/inventory/src/inventoryImp.cpp index dca1943e7a..81b3a0958b 100644 --- a/src/modules/inventory/src/inventoryImp.cpp +++ b/src/modules/inventory/src/inventoryImp.cpp @@ -1242,7 +1242,7 @@ void Inventory::CleanMetadata() m_spDBSync = std::make_unique(HostType::AGENT, DbEngineType::SQLITE3, m_dbFilePath, - METADATA_SQL_STATEMENT, + GetCreateStatement(), DbManagement::PERSISTENT); for (const auto& key : TABLE_TO_KEY_MAP) { if(!ReadMetadata(key.second).empty()){