Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle agent centralized configuration commands #223

Merged
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
dda6c02
feat: add boilerplate files for CentralizedConfiguration
jr0me Oct 7, 2024
c28f302
feat: add module wrapper interface methods to CentralizedConfiguration
jr0me Oct 8, 2024
8c36877
feat: implement CentralizedConfiguration::Setup
jr0me Oct 9, 2024
0b85dc5
fix: toml and Logger are public dependencies of ConfigurationParser
jr0me Oct 9, 2024
079723b
feat: introduce ExecuteCommand in CentralizedConfiguration
jr0me Oct 9, 2024
c0fdbf2
feat: add basic handling of CentralizedConfiguration commands
jr0me Oct 9, 2024
a547707
feat: add SetGroupIdFunction to CentralizedConfiguration
jr0me Oct 10, 2024
b28ba08
refactor: CentralizedConfiguration tests for better readability and m…
jr0me Oct 10, 2024
c0fd320
feat: test failure when SetGroupIdFunction is not set
jr0me Oct 14, 2024
964a82d
feat: catch json parsing errors
jr0me Oct 14, 2024
7ff5e34
feat: add function setter to configure how to download group configur…
jr0me Oct 15, 2024
1e903e4
refactor: use type alias to improve readability
jr0me Oct 17, 2024
021499b
feat: use download group config files and udpate tests
jr0me Oct 17, 2024
c87707e
feat: GetGroupIdFunction and update tests
jr0me Oct 15, 2024
c4d0b6b
feat: add SetMessageQueue method to CentralizedConfiguration
jr0me Oct 16, 2024
e6d4b49
feat: add CentralizedConfiguration module to ModuleManager
jr0me Oct 16, 2024
9e3bc20
feat: set CentralizedConfiguration functions to set and get groups an…
jr0me Oct 17, 2024
32dc10f
feat: add documentation to the CentralizedConfiguration
jr0me Oct 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/agent/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,22 @@ list(APPEND SOURCES

add_library(Agent ${SOURCES})
target_include_directories(Agent PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
target_link_libraries(Agent PUBLIC ConfigurationParser Communicator AgentInfo CommandHandler MultiTypeQueue ModuleManager ModuleCommand PRIVATE OpenSSL::SSL OpenSSL::Crypto Boost::asio Boost::beast)
target_link_libraries(Agent
cborla marked this conversation as resolved.
Show resolved Hide resolved
PUBLIC
ConfigurationParser
Communicator
AgentInfo
CommandHandler
MultiTypeQueue
ModuleManager
ModuleCommand
CentralizedConfiguration
PRIVATE
OpenSSL::SSL
OpenSSL::Crypto
Boost::asio
Boost::beast
)

include(../cmake/ConfigureTarget.cmake)
configure_target(Agent)
Expand Down
2 changes: 1 addition & 1 deletion src/agent/configuration_parser/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ find_package(toml11 CONFIG REQUIRED)

add_library(ConfigurationParser src/configuration_parser.cpp)
target_include_directories(ConfigurationParser PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(ConfigurationParser PRIVATE toml11::toml11 Logger)
target_link_libraries(ConfigurationParser PUBLIC toml11::toml11 Logger)

include(../../cmake/ConfigureTarget.cmake)
configure_target(ConfigurationParser)
Expand Down
2 changes: 2 additions & 0 deletions src/agent/include/agent.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <agent_info.hpp>
#include <centralized_configuration.hpp>
#include <command_handler.hpp>
#include <communicator.hpp>
#include <configuration_parser.hpp>
Expand Down Expand Up @@ -32,4 +33,5 @@ class Agent
communicator::Communicator m_communicator;
command_handler::CommandHandler m_commandHandler;
ModuleManager m_moduleManager;
centralized_configuration::CentralizedConfiguration m_centralizedConfiguration;
};
10 changes: 10 additions & 0 deletions src/agent/src/agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ Agent::Agent(const std::string& configPath, std::unique_ptr<ISignalHandler> sign
{ return m_configurationParser.GetConfig<std::string>(std::move(table), std::move(key)); })
, m_moduleManager(m_messageQueue, m_configurationParser)
{
m_centralizedConfiguration.SetGroupIdFunction([this](const std::vector<std::string>& groups)
{ return m_agentInfo.SetGroups(groups); });

m_centralizedConfiguration.GetGroupIdFunction([this]() { return m_agentInfo.GetGroups(); });

m_centralizedConfiguration.SetDownloadGroupFilesFunction(
[this](const std::string& groupId, const std::string& destinationPath)
{ return m_communicator.GetGroupConfigurationFromManager(groupId, destinationPath); });

m_taskManager.Start(std::thread::hardware_concurrency());
}

Expand Down Expand Up @@ -55,6 +64,7 @@ void Agent::Run()
{ return DispatchCommand(cmd, m_moduleManager.GetModule(cmd.Module), m_messageQueue); }));

m_moduleManager.AddModule(Inventory::Instance());
m_moduleManager.AddModule(m_centralizedConfiguration);
m_moduleManager.Setup();
m_taskManager.EnqueueTask([this]() { m_moduleManager.Start(); });

Expand Down
1 change: 1 addition & 0 deletions src/modules/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ project(ModuleManager)
include(../cmake/CommonSettings.cmake)
set_common_settings()

add_subdirectory(centralized_configuration)
add_subdirectory(inventory)

add_library(ModuleManager src/moduleManager.cpp)
Expand Down
20 changes: 20 additions & 0 deletions src/modules/centralized_configuration/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 3.22)

project(CentralizedConfiguration)

include(../../cmake/CommonSettings.cmake)
set_common_settings()

include_directories(${CMAKE_SOURCE_DIR}/common/logger/include)

add_library(CentralizedConfiguration src/centralized_configuration.cpp)
target_include_directories(CentralizedConfiguration PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(CentralizedConfiguration PUBLIC ConfigurationParser ModuleManager MultiTypeQueue)

include(../../cmake/ConfigureTarget.cmake)
configure_target(CentralizedConfiguration)

if(BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

#include <configuration_parser.hpp>
#include <moduleWrapper.hpp>
#include <multitype_queue.hpp>

#include <filesystem>
#include <functional>
#include <string>
#include <vector>

namespace centralized_configuration
{
class CentralizedConfiguration
{
public:
using SetGroupIdFunctionType = std::function<void(const std::vector<std::string>&)>;
using GetGroupIdFunctionType = std::function<std::vector<std::string>()>;
using DownloadGroupFilesFunctionType = std::function<bool(const std::string&, const std::string&)>;

void Start() const;
void Setup(const configuration::ConfigurationParser&) const;
void Stop() const;
Co_CommandExecutionResult ExecuteCommand(std::string command);
std::string Name() const;
void SetMessageQueue(const std::shared_ptr<IMultiTypeQueue>);

void SetGroupIdFunction(SetGroupIdFunctionType setGroupIdFunction);
void GetGroupIdFunction(GetGroupIdFunctionType getGroupIdFunction);
void SetDownloadGroupFilesFunction(DownloadGroupFilesFunctionType downloadGroupFilesFunction);

private:
SetGroupIdFunctionType m_setGroupIdFunction;
GetGroupIdFunctionType m_getGroupIdFunction;
DownloadGroupFilesFunctionType m_downloadGroupFilesFunction;
};
} // namespace centralized_configuration
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#include <centralized_configuration.hpp>

#include <module_command/command_entry.hpp>

#include <nlohmann/json.hpp>

#include <filesystem>

namespace centralized_configuration
{
void CentralizedConfiguration::Start() const
{
}

void CentralizedConfiguration::Setup(const configuration::ConfigurationParser&) const
{
}

void CentralizedConfiguration::Stop() const
{
}

// NOLINTNEXTLINE(performance-unnecessary-value-param)
Co_CommandExecutionResult CentralizedConfiguration::ExecuteCommand(const std::string command)
{
try
{
const auto commnandAsJson = nlohmann::json::parse(command);

if (commnandAsJson["command"] == "set-group")
{
if (m_setGroupIdFunction && m_downloadGroupFilesFunction)
{
const auto groupIds = commnandAsJson["groups"].get<std::vector<std::string>>();

m_setGroupIdFunction(groupIds);

for (const auto& groupId : groupIds)
{
m_downloadGroupFilesFunction(
groupId,
std::filesystem::temp_directory_path().string()
);
}

// TODO validate groupFiles, apply configuration

co_return module_command::CommandExecutionResult{
module_command::Status::SUCCESS,
"CentralizedConfiguration group set"
};
}
else
{
co_return module_command::CommandExecutionResult{
module_command::Status::FAILURE,
"CentralizedConfiguration group set failed, no function set"
};
}
}
else if (commnandAsJson["command"] == "update-group")
{
if (m_getGroupIdFunction && m_downloadGroupFilesFunction)
{
const auto groupIds = m_getGroupIdFunction();

for (const auto& groupId : groupIds)
{
m_downloadGroupFilesFunction(
groupId,
std::filesystem::temp_directory_path().string()
);
}

// TODO validate groupFiles, apply configuration

co_return module_command::CommandExecutionResult{
module_command::Status::SUCCESS,
"CentralizedConfiguration group updated"
};
}
else
{
co_return module_command::CommandExecutionResult{
module_command::Status::FAILURE,
"CentralizedConfiguration group set failed, no function set"
};
}
}
}
catch (const nlohmann::json::exception&)
{
co_return module_command::CommandExecutionResult{
module_command::Status::FAILURE,
"CentralizedConfiguration error while parsing command"
};
}

co_return module_command::CommandExecutionResult{
module_command::Status::FAILURE,
"CentralizedConfiguration command not recognized"
};
}

std::string CentralizedConfiguration::Name() const
{
return "CentralizedConfiguration";
}

void CentralizedConfiguration::SetMessageQueue(const std::shared_ptr<IMultiTypeQueue>)
{
}

void CentralizedConfiguration::SetGroupIdFunction(SetGroupIdFunctionType setGroupIdFunction)
{
m_setGroupIdFunction = std::move(setGroupIdFunction);
}

void CentralizedConfiguration::GetGroupIdFunction(GetGroupIdFunctionType getGroupIdFunction)
{
m_getGroupIdFunction = std::move(getGroupIdFunction);
}

void CentralizedConfiguration::SetDownloadGroupFilesFunction(DownloadGroupFilesFunctionType downloadGroupFilesFunction)
{
m_downloadGroupFilesFunction = std::move(downloadGroupFilesFunction);
}
} // namespace centralized_configuration
7 changes: 7 additions & 0 deletions src/modules/centralized_configuration/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
find_package(GTest CONFIG REQUIRED)

add_executable(centralized_configuration_test centralized_configuration_tests.cpp)
configure_target(centralized_configuration_test)
target_include_directories(centralized_configuration_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_link_libraries(centralized_configuration_test PRIVATE CentralizedConfiguration GTest::gtest GTest::gmock)
add_test(NAME CentralizedConfiguration COMMAND centralized_configuration_test)
Loading
Loading