Skip to content

Commit 4a9cd0b

Browse files
authored
Merge pull request wazuh#29357 from wazuh/enhancement/29323-engine-archiver
Adds archives to the Engine
2 parents 41ef781 + 465565e commit 4a9cd0b

File tree

37 files changed

+2461
-102
lines changed

37 files changed

+2461
-102
lines changed

docs/ref/modules/engine/spec.yaml

Lines changed: 101 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ tags:
2121
description: "Operations for managing key-value databases"
2222
- name: Tester
2323
description: "Operations for testing and validating policies"
24+
- name: Archiver
25+
description: "Operations for managing the archives. By default a file 'archives.json' is created at '/var/lib/wazuh-server/archives.json' where all events received by the Engine are stored."
2426

2527
#################################################################################
2628
# Paths
@@ -133,7 +135,7 @@ paths:
133135
summary: The requested collection does not exist
134136
value:
135137
status: "ERROR"
136-
error: "Invalid collection type \"non-exist\""
138+
error: 'Invalid collection type "non-exist"'
137139
invalid_format:
138140
summary: The requested format does not exist
139141
value:
@@ -143,12 +145,12 @@ paths:
143145
summary: The asset content does not have a name
144146
value:
145147
status: "ERROR"
146-
error: "Invalid content name 'documentation': Invalid collection type \"documentation\""
148+
error: 'Invalid content name ''documentation'': Invalid collection type "documentation"'
147149
name_type_mismatch:
148150
summary: The asset name in the content does not match the asset type
149151
value:
150152
status: "ERROR"
151-
error: "Invalid content name 'non-exist/documentation/0': Invalid type \"non-exist\""
153+
error: 'Invalid content name ''non-exist/documentation/0'': Invalid type "non-exist"'
152154
already_exists:
153155
summary: The asset already exists currently
154156
value:
@@ -198,7 +200,7 @@ paths:
198200
summary: The requested collection does not exist
199201
value:
200202
status: "ERROR"
201-
error: "Invalid collection type \"non-exist\""
203+
error: 'Invalid collection type "non-exist"'
202204
invalid_format:
203205
summary: The requested format does not exist
204206
value:
@@ -208,7 +210,7 @@ paths:
208210
summary: The requested asset name has an invalid format
209211
value:
210212
status: "ERROR"
211-
error: "Invalid name \"decoder/core-wazuh-message/0/other\" received, a name with 1, 2 or 3 parts was expected"
213+
error: 'Invalid name "decoder/core-wazuh-message/0/other" received, a name with 1, 2 or 3 parts was expected'
212214
"500":
213215
$ref: "#/components/responses/InternalServerError_500"
214216

@@ -300,7 +302,7 @@ paths:
300302
summary: Invalid format of the asset name
301303
value:
302304
status: "ERROR"
303-
error: "Invalid name \"decoder/documentation/0/0\" received, a name with 1, 2 or 3 parts was expected"
305+
error: 'Invalid name "decoder/documentation/0/0" received, a name with 1, 2 or 3 parts was expected'
304306
"500":
305307
$ref: "#/components/responses/InternalServerError_500"
306308

@@ -336,7 +338,7 @@ paths:
336338
summary: Invalid helper function
337339
value:
338340
status: "ERROR"
339-
error: "In stage 'normalize' builder for block 'map' failed with error: Failed to build operation '@timestamp: map(\"non-exist()\")': Field '@timestamp' value validation failed: Invalid date"
341+
error: 'In stage ''normalize'' builder for block ''map'' failed with error: Failed to build operation ''@timestamp: map("non-exist()")'': Field ''@timestamp'' value validation failed: Invalid date'
340342
invalid_map_structure:
341343
summary: Invalid map structure
342344
value:
@@ -2238,6 +2240,98 @@ paths:
22382240
error: "Cannot download database from 'https://raw.githubusercontent.com/wazuh/wazuh/blob/main/src/engine/test/integration_tests/geo/data/base.mmdb': Failed to download file from 'https://raw.githubusercontent.com/wazuh/wazuh/blob/main/src/engine/test/integration_tests/geo/data/base.mmdb', error: HTTP response code said error, status code: 404."
22392241
"500":
22402242
$ref: "#/components/responses/InternalServerError_500"
2243+
#################################
2244+
# Archiver
2245+
#################################
2246+
/archiver/activate:
2247+
post:
2248+
tags:
2249+
- Archiver
2250+
summary: Activate the archiver
2251+
description: |
2252+
This endpoint activates the archiver in the system.
2253+
requestBody:
2254+
required: true
2255+
content:
2256+
application/json:
2257+
schema:
2258+
$ref: "#/components/schemas/EmptyRequest"
2259+
responses:
2260+
"200":
2261+
$ref: "#/components/responses/GenericSuccess_200"
2262+
"400":
2263+
description: Bad Request
2264+
content:
2265+
application/json:
2266+
schema:
2267+
$ref: "#/components/responses/BadRequest_400"
2268+
"500":
2269+
$ref: "#/components/responses/InternalServerError_500"
2270+
/archiver/deactivate:
2271+
post:
2272+
tags:
2273+
- Archiver
2274+
summary: Deactivate the archiver
2275+
description: |
2276+
This endpoint deactivates the archiver in the system.
2277+
requestBody:
2278+
required: true
2279+
content:
2280+
application/json:
2281+
schema:
2282+
$ref: "#/components/schemas/EmptyRequest"
2283+
responses:
2284+
"200":
2285+
$ref: "#/components/responses/GenericSuccess_200"
2286+
"400":
2287+
description: Bad Request
2288+
content:
2289+
application/json:
2290+
schema:
2291+
$ref: "#/components/responses/BadRequest_400"
2292+
"500":
2293+
$ref: "#/components/responses/InternalServerError_500"
2294+
/archiver/status:
2295+
post:
2296+
tags:
2297+
- Archiver
2298+
summary: Get the status of the archiver
2299+
description: |
2300+
This endpoint retrieves the current status of the archiver.
2301+
requestBody:
2302+
required: true
2303+
content:
2304+
application/json:
2305+
schema:
2306+
$ref: "#/components/schemas/EmptyRequest"
2307+
responses:
2308+
"200":
2309+
description: Successfully retrieved archiver status
2310+
content:
2311+
application/json:
2312+
schema:
2313+
$ref: "#/components/schemas/ArchiverStatus_Response"
2314+
examples:
2315+
archiver_active:
2316+
summary: Archiver is active
2317+
value:
2318+
status: "OK"
2319+
error: null
2320+
active: true
2321+
archiver_inactive:
2322+
summary: Archiver is inactive
2323+
value:
2324+
status: "OK"
2325+
error: null
2326+
active: false
2327+
"400":
2328+
description: Bad Request
2329+
content:
2330+
application/json:
2331+
schema:
2332+
$ref: "#/components/responses/BadRequest_400"
2333+
"500":
2334+
$ref: "#/components/responses/InternalServerError_500"
22412335

22422336
#################################################################################
22432337
# Components

src/engine/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ add_subdirectory(${ENGINE_SOURCE_DIR}/queue)
229229
add_subdirectory(${ENGINE_SOURCE_DIR}/fs)
230230
add_subdirectory(${ENGINE_SOURCE_DIR}/keystore)
231231
add_subdirectory(${ENGINE_SOURCE_DIR}/httpsrv)
232+
add_subdirectory(${ENGINE_SOURCE_DIR}/archiver)
232233

233234
target_link_libraries(main
234235
base
@@ -254,6 +255,7 @@ target_link_libraries(main
254255
httpsrv
255256
api::event
256257
queue
258+
archiver
257259
)
258260

259261
# If ASAN, UBSAN or any other sanitizers are enabled do not link with static libraries

src/engine/source/api/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ add_subdirectory(router)
66
add_subdirectory(tester)
77
add_subdirectory(kvdb)
88
add_subdirectory(event)
9+
add_subdirectory(archiver)
910

1011
add_library(api INTERFACE)
1112
target_include_directories(api INTERFACE
@@ -19,4 +20,5 @@ target_link_libraries(api INTERFACE
1920
api::tester
2021
api::kvdb
2122
api::event
23+
api::archiver
2224
)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
set(SRC_DIR ${CMAKE_CURRENT_LIST_DIR}/src)
2+
set(INC_DIR ${CMAKE_CURRENT_LIST_DIR}/include)
3+
4+
add_library(api_archiver STATIC
5+
${SRC_DIR}/handlers.cpp
6+
)
7+
target_include_directories(api_archiver
8+
PUBLIC
9+
${INC_DIR}
10+
PRIVATE
11+
${SRC_DIR}
12+
)
13+
target_link_libraries(api_archiver
14+
PUBLIC
15+
api::adapter
16+
archiver::iface
17+
)
18+
add_library(api::archiver ALIAS api_archiver)
19+
20+
if(ENGINE_BUILD_TEST)
21+
set(TEST_SRC_DIR ${CMAKE_CURRENT_LIST_DIR}/test/src)
22+
set(UNIT_SRC_DIR ${TEST_SRC_DIR}/unit)
23+
24+
add_executable(api_archiver_utest
25+
${UNIT_SRC_DIR}/handlers_test.cpp
26+
)
27+
target_include_directories(api_archiver_utest
28+
PRIVATE
29+
${UNIT_SRC_DIR}
30+
)
31+
target_link_libraries(api_archiver_utest
32+
PRIVATE
33+
api::archiver
34+
GTest::gtest_main
35+
api::adapter::test
36+
archiver::mocks
37+
)
38+
gtest_discover_tests(api_archiver_utest)
39+
endif()
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef _API_ARCHIVER_HANDLERS_HPP
2+
#define _API_ARCHIVER_HANDLERS_HPP
3+
4+
#include <api/adapter/adapter.hpp>
5+
#include <archiver/iarchiver.hpp>
6+
#include <base/baseTypes.hpp>
7+
8+
namespace api::archiver::handlers
9+
{
10+
adapter::RouteHandler activateArchiver(const std::shared_ptr<::archiver::IArchiver>& archiver);
11+
12+
adapter::RouteHandler deactivateArchiver(const std::shared_ptr<::archiver::IArchiver>& archiver);
13+
14+
adapter::RouteHandler getArchiverStatus(const std::shared_ptr<::archiver::IArchiver>& archiver);
15+
16+
inline void registerHandlers(const std::shared_ptr<::archiver::IArchiver>& archiver,
17+
const std::shared_ptr<httpsrv::Server>& server)
18+
{
19+
server->addRoute(httpsrv::Method::POST, "/archiver/activate", activateArchiver(archiver));
20+
server->addRoute(httpsrv::Method::POST, "/archiver/deactivate", deactivateArchiver(archiver));
21+
server->addRoute(httpsrv::Method::POST, "/archiver/status", getArchiverStatus(archiver));
22+
}
23+
} // namespace api::archiver::handlers
24+
25+
#endif // _API_ARCHIVER_HANDLERS_HPP
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#include <api/archiver/handlers.hpp>
2+
#include <base/logging.hpp>
3+
#include <eMessages/archiver.pb.h>
4+
5+
namespace api::archiver::handlers
6+
{
7+
8+
namespace eArchiver = adapter::eEngine::archiver;
9+
namespace eEngine = adapter::eEngine;
10+
11+
adapter::RouteHandler activateArchiver(const std::shared_ptr<::archiver::IArchiver>& archiver)
12+
{
13+
return [lambdaName = logging::getLambdaName(__FUNCTION__, "apiHandler"),
14+
weakArchiver = std::weak_ptr(archiver)](const auto& req, auto& res)
15+
{
16+
using RequestType = eArchiver::ArchiverActivate_Request;
17+
using ResponseType = eEngine::GenericStatus_Response;
18+
19+
auto result = adapter::getReqAndHandler<RequestType, ResponseType, ::archiver::IArchiver>(req, weakArchiver);
20+
if (adapter::isError(result))
21+
{
22+
res = adapter::getErrorResp(result);
23+
return;
24+
}
25+
26+
auto [archiver, protoReq] = adapter::getRes(result);
27+
28+
archiver->activate();
29+
30+
ResponseType eResponse;
31+
eResponse.set_status(eEngine::ReturnStatus::OK);
32+
res = adapter::userResponse(eResponse);
33+
};
34+
}
35+
36+
adapter::RouteHandler deactivateArchiver(const std::shared_ptr<::archiver::IArchiver>& archiver)
37+
{
38+
return [lambdaName = logging::getLambdaName(__FUNCTION__, "apiHandler"),
39+
weakArchiver = std::weak_ptr(archiver)](const auto& req, auto& res)
40+
{
41+
using RequestType = eArchiver::ArchiverDeactivate_Request;
42+
using ResponseType = eEngine::GenericStatus_Response;
43+
44+
auto result = adapter::getReqAndHandler<RequestType, ResponseType, ::archiver::IArchiver>(req, weakArchiver);
45+
if (adapter::isError(result))
46+
{
47+
res = adapter::getErrorResp(result);
48+
return;
49+
}
50+
51+
auto [archiver, protoReq] = adapter::getRes(result);
52+
53+
archiver->deactivate();
54+
55+
ResponseType eResponse;
56+
eResponse.set_status(eEngine::ReturnStatus::OK);
57+
res = adapter::userResponse(eResponse);
58+
};
59+
}
60+
61+
adapter::RouteHandler getArchiverStatus(const std::shared_ptr<::archiver::IArchiver>& archiver)
62+
{
63+
return [lambdaName = logging::getLambdaName(__FUNCTION__, "apiHandler"),
64+
weakArchiver = std::weak_ptr(archiver)](const auto& req, auto& res)
65+
{
66+
using RequestType = eArchiver::ArchiverStatus_Request;
67+
using ResponseType = eArchiver::ArchiverStatus_Response;
68+
69+
auto result = adapter::getReqAndHandler<RequestType, ResponseType, ::archiver::IArchiver>(req, weakArchiver);
70+
if (adapter::isError(result))
71+
{
72+
res = adapter::getErrorResp(result);
73+
return;
74+
}
75+
76+
auto [archiver, protoReq] = adapter::getRes(result);
77+
78+
// Get the status
79+
const auto isActive = archiver->isActive();
80+
81+
ResponseType eResponse;
82+
eResponse.set_status(eEngine::ReturnStatus::OK);
83+
eResponse.set_active(isActive);
84+
res = adapter::userResponse(eResponse);
85+
};
86+
}
87+
} // namespace api::archiver::handlers

0 commit comments

Comments
 (0)