mirror of
https://github.com/openappsec/openappsec.git
synced 2025-06-28 16:41:02 +03:00
Jun 9th update
This commit is contained in:
parent
fd5d093b24
commit
51b2e6d0d7
@ -4,7 +4,6 @@ add_subdirectory(signal_handler)
|
||||
add_subdirectory(gradual_deployment)
|
||||
add_subdirectory(packet)
|
||||
add_subdirectory(pending_key)
|
||||
add_subdirectory(health_check_manager)
|
||||
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(attachment-intakers)
|
||||
|
@ -36,7 +36,6 @@ public:
|
||||
title,
|
||||
audience_team,
|
||||
obj,
|
||||
false,
|
||||
MessageCategory::GENERIC,
|
||||
std::forward<Args>(args)...
|
||||
)
|
||||
@ -48,26 +47,6 @@ public:
|
||||
const std::string &title,
|
||||
const ReportIS::AudienceTeam &audience_team,
|
||||
const T &obj,
|
||||
bool is_async_message,
|
||||
Args ...args)
|
||||
:
|
||||
ReportMessaging(
|
||||
title,
|
||||
audience_team,
|
||||
obj,
|
||||
is_async_message,
|
||||
MessageCategory::GENERIC,
|
||||
std::forward<Args>(args)...
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename ...Args, typename T>
|
||||
ReportMessaging(
|
||||
const std::string &title,
|
||||
const ReportIS::AudienceTeam &audience_team,
|
||||
const T &obj,
|
||||
bool is_async_message,
|
||||
const MessageCategory &message_type,
|
||||
Args ...args)
|
||||
:
|
||||
@ -77,7 +56,6 @@ public:
|
||||
ReportIS::Severity::INFO,
|
||||
ReportIS::Priority::LOW,
|
||||
obj,
|
||||
is_async_message,
|
||||
message_type,
|
||||
std::forward<Args>(args)...
|
||||
)
|
||||
@ -99,7 +77,6 @@ public:
|
||||
severity,
|
||||
priority,
|
||||
obj,
|
||||
false,
|
||||
MessageCategory::GENERIC,
|
||||
std::forward<Args>(args)...
|
||||
)
|
||||
@ -114,7 +91,6 @@ public:
|
||||
const ReportIS::Severity &severity,
|
||||
const ReportIS::Priority &priority,
|
||||
const T &obj,
|
||||
bool _is_async_message,
|
||||
const MessageCategory &message_type,
|
||||
Args ...args)
|
||||
:
|
||||
@ -131,7 +107,6 @@ public:
|
||||
std::chrono::seconds(0),
|
||||
std::forward<Args>(args)...
|
||||
),
|
||||
is_async_message(_is_async_message),
|
||||
message_type_tag(message_type)
|
||||
{
|
||||
report << LogField("eventObject", obj);
|
||||
@ -141,11 +116,13 @@ public:
|
||||
|
||||
ReportMessaging & operator<<(const LogField &field);
|
||||
|
||||
Maybe<void, HTTPResponse> sendReportSynchronously();
|
||||
|
||||
void setForceBuffering(bool _force_buffering);
|
||||
|
||||
private:
|
||||
Report report;
|
||||
bool is_async_message;
|
||||
bool is_async_message = true;
|
||||
bool force_buffering = false;
|
||||
MessageCategory message_type_tag;
|
||||
};
|
||||
|
@ -24,6 +24,7 @@ static const string url = "/api/v1/agents/events";
|
||||
ReportMessaging::~ReportMessaging()
|
||||
{
|
||||
if (!Singleton::exists<I_Messaging>()) return;
|
||||
if (!is_async_message) return;
|
||||
|
||||
LogRest log_rest(report);
|
||||
|
||||
@ -47,6 +48,25 @@ ReportMessaging::operator<<(const LogField &field)
|
||||
return *this;
|
||||
}
|
||||
|
||||
class LogRestWithReply : public LogRest
|
||||
{
|
||||
public:
|
||||
LogRestWithReply(const Report &report) : LogRest(report) {}
|
||||
|
||||
bool loadJson(const string &) const { return true; }
|
||||
};
|
||||
|
||||
Maybe<void, HTTPResponse>
|
||||
ReportMessaging::sendReportSynchronously()
|
||||
{
|
||||
is_async_message = false;
|
||||
|
||||
LogRestWithReply log_rest(report);
|
||||
|
||||
auto messaging = Singleton::Consume<I_Messaging>::by<ReportMessaging>();
|
||||
return messaging->sendSyncMessage(HTTPMethod::POST, url, log_rest, message_type_tag);
|
||||
}
|
||||
|
||||
void
|
||||
ReportMessaging::setForceBuffering(bool _force_buffering)
|
||||
{
|
||||
|
@ -103,7 +103,48 @@ TEST_F(ReportMessagingTest, title_only)
|
||||
_
|
||||
)
|
||||
).Times(1);
|
||||
ReportMessaging("test", ReportIS::AudienceTeam::AGENT_CORE, 1, true, ReportIS::Tags::ACCESS_CONTROL);
|
||||
ReportMessaging("test", ReportIS::AudienceTeam::AGENT_CORE, 1, ReportIS::Tags::ACCESS_CONTROL);
|
||||
}
|
||||
|
||||
TEST_F(ReportMessagingTest, sync_sending)
|
||||
{
|
||||
EXPECT_CALL(
|
||||
mock_messaging,
|
||||
sendSyncMessage(
|
||||
_,
|
||||
_,
|
||||
"{\n"
|
||||
" \"log\": {\n"
|
||||
" \"eventTime\": \"Best Time ever\",\n"
|
||||
" \"eventName\": \"test\",\n"
|
||||
" \"eventSeverity\": \"Info\",\n"
|
||||
" \"eventPriority\": \"Low\",\n"
|
||||
" \"eventType\": \"Event Driven\",\n"
|
||||
" \"eventLevel\": \"Log\",\n"
|
||||
" \"eventLogLevel\": \"info\",\n"
|
||||
" \"eventAudience\": \"Internal\",\n"
|
||||
" \"eventAudienceTeam\": \"Agent Core\",\n"
|
||||
" \"eventFrequency\": 0,\n"
|
||||
" \"eventTags\": [\n"
|
||||
" \"Access Control\"\n"
|
||||
" ],\n"
|
||||
" \"eventSource\": {\n"
|
||||
" \"eventTraceId\": \"\",\n"
|
||||
" \"eventSpanId\": \"\",\n"
|
||||
" \"issuingEngineVersion\": \"\",\n"
|
||||
" \"serviceName\": \"Unnamed Nano Service\"\n"
|
||||
" },\n"
|
||||
" \"eventData\": {\n"
|
||||
" \"eventObject\": 1\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}",
|
||||
_,
|
||||
_
|
||||
)
|
||||
).WillOnce(Return(HTTPResponse(HTTPStatusCode::HTTP_OK, "response!!")));
|
||||
ReportMessaging report("test", ReportIS::AudienceTeam::AGENT_CORE, 1, ReportIS::Tags::ACCESS_CONTROL);
|
||||
EXPECT_TRUE(report.sendReportSynchronously().ok());
|
||||
}
|
||||
|
||||
TEST_F(ReportMessagingTest, with_buffering)
|
||||
@ -144,7 +185,7 @@ TEST_F(ReportMessagingTest, with_buffering)
|
||||
true
|
||||
)
|
||||
).Times(1);
|
||||
ReportMessaging report("test", ReportIS::AudienceTeam::AGENT_CORE, 1, true, ReportIS::Tags::ACCESS_CONTROL);
|
||||
ReportMessaging report("test", ReportIS::AudienceTeam::AGENT_CORE, 1, ReportIS::Tags::ACCESS_CONTROL);
|
||||
report.setForceBuffering(true);
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,8 @@ add_subdirectory(manifest_controller)
|
||||
add_subdirectory(update_communication)
|
||||
add_subdirectory(details_resolver)
|
||||
add_subdirectory(health_check)
|
||||
add_subdirectory(health_check_manager)
|
||||
add_subdirectory(env_details)
|
||||
add_subdirectory(updates_process_reporter)
|
||||
|
||||
#add_subdirectory(orchestration_ut)
|
||||
|
@ -3,5 +3,5 @@ link_directories(${BOOST_ROOT}/lib)
|
||||
add_unit_test(
|
||||
health_check_ut
|
||||
"health_check_ut.cc"
|
||||
"health_check;messaging;mainloop;singleton;agent_details;config;logging;metric;event_is;health_check_manager;-lboost_regex;-lboost_system"
|
||||
"health_check;updates_process_reporter;messaging;mainloop;singleton;agent_details;config;logging;metric;event_is;health_check_manager;-lboost_regex;-lboost_system"
|
||||
)
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "config.h"
|
||||
#include "cereal/archives/json.hpp"
|
||||
#include "customized_cereal_map.h"
|
||||
#include "updates_process_event.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -79,19 +80,22 @@ class HealthCheckValue
|
||||
public:
|
||||
HealthCheckValue() = default;
|
||||
|
||||
HealthCheckValue(HealthCheckStatus raw_status, const map<string, HealthCheckStatusReply> &descriptions)
|
||||
HealthCheckValue(HealthCheckStatus raw_status, const HealthCheckStatusReply &description)
|
||||
:
|
||||
status(raw_status)
|
||||
{
|
||||
for (const auto &single_stat : descriptions) {
|
||||
if (single_stat.second.getStatus() == HealthCheckStatus::HEALTHY) {
|
||||
dbgTrace(D_HEALTH_CHECK_MANAGER) << "Ignoring healthy status reply. Comp name: " << single_stat.first;
|
||||
continue;
|
||||
}
|
||||
if (description.getStatus() == HealthCheckStatus::HEALTHY) {
|
||||
dbgTrace(D_HEALTH_CHECK_MANAGER)
|
||||
<< "Ignoring healthy status reply. Comp name: "
|
||||
<< description.getCompName();
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto &status : single_stat.second.getExtendedStatus()) {
|
||||
errors.push_back(HealthCheckError(single_stat.first + " " + status.first, status.second));
|
||||
}
|
||||
for (const auto &extended_status : description.getExtendedStatus()) {
|
||||
errors.push_back(
|
||||
HealthCheckError(description.getCompName() + " " + extended_status.first,
|
||||
extended_status.second
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,9 +117,9 @@ private:
|
||||
class HealthCheckPatch : public ClientRest
|
||||
{
|
||||
public:
|
||||
HealthCheckPatch(HealthCheckStatus raw_status, const map<string, HealthCheckStatusReply> &descriptions)
|
||||
HealthCheckPatch(HealthCheckStatus raw_status, const HealthCheckStatusReply &description)
|
||||
{
|
||||
health_check = HealthCheckValue(raw_status, descriptions);
|
||||
health_check = HealthCheckValue(raw_status, description);
|
||||
}
|
||||
|
||||
C2S_LABEL_PARAM(HealthCheckValue, health_check, "healthCheck");
|
||||
@ -123,7 +127,8 @@ public:
|
||||
|
||||
class HealthCheckManager::Impl
|
||||
:
|
||||
Singleton::Provide<I_Health_Check_Manager>::From<HealthCheckManager>
|
||||
Singleton::Provide<I_Health_Check_Manager>::From<HealthCheckManager>,
|
||||
public Listener<UpdatesProcessEvent>
|
||||
{
|
||||
public:
|
||||
void
|
||||
@ -132,6 +137,7 @@ public:
|
||||
auto rest = Singleton::Consume<I_RestApi>::by<HealthCheckManager>();
|
||||
rest->addRestCall<HealthCheckOnDemand>(RestAction::SHOW, "health-check-on-demand");
|
||||
|
||||
registerListener();
|
||||
int interval_in_seconds =
|
||||
getProfileAgentSettingWithDefault<int>(30, "agent.healthCheck.intervalInSeconds");
|
||||
|
||||
@ -157,9 +163,62 @@ public:
|
||||
void
|
||||
printRepliesHealthStatus(ofstream &oputput_file)
|
||||
{
|
||||
getRegisteredComponentsHealthStatus();
|
||||
cereal::JSONOutputArchive ar(oputput_file);
|
||||
ar(cereal::make_nvp("allComponentsHealthCheckReplies", all_comps_health_status));
|
||||
ar(cereal::make_nvp(health_check_reply.getCompName(), health_check_reply));
|
||||
}
|
||||
|
||||
void
|
||||
upon(const UpdatesProcessEvent &event)
|
||||
{
|
||||
|
||||
OrchestrationStatusFieldType status_field_type = event.getStatusFieldType();
|
||||
HealthCheckStatus _status = convertResultToHealthCheckStatus(event.getResult());
|
||||
string status_field_type_str = convertOrchestrationStatusFieldTypeToStr(status_field_type);
|
||||
|
||||
extended_status[status_field_type_str] =
|
||||
_status == HealthCheckStatus::HEALTHY ?
|
||||
"Success" :
|
||||
event.parseDescription();
|
||||
field_types_status[status_field_type_str] = _status;
|
||||
|
||||
switch(_status) {
|
||||
case HealthCheckStatus::UNHEALTHY: {
|
||||
general_health_aggregated_status = HealthCheckStatus::UNHEALTHY;
|
||||
break;
|
||||
}
|
||||
case HealthCheckStatus::DEGRADED: {
|
||||
for (const auto &type_status : field_types_status) {
|
||||
if ((type_status.first != status_field_type_str)
|
||||
&& (type_status.second == HealthCheckStatus::UNHEALTHY))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
general_health_aggregated_status = HealthCheckStatus::DEGRADED;
|
||||
break;
|
||||
}
|
||||
case HealthCheckStatus::HEALTHY: {
|
||||
for (const auto &type_status : field_types_status) {
|
||||
if ((type_status.first != status_field_type_str)
|
||||
&& (type_status.second == HealthCheckStatus::UNHEALTHY
|
||||
|| type_status.second == HealthCheckStatus::DEGRADED)
|
||||
)
|
||||
{
|
||||
break;
|
||||
}
|
||||
general_health_aggregated_status = HealthCheckStatus::HEALTHY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HealthCheckStatus::IGNORED: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
health_check_reply = HealthCheckStatusReply(
|
||||
"Orchestration",
|
||||
general_health_aggregated_status,
|
||||
extended_status
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -168,9 +227,10 @@ private:
|
||||
{
|
||||
dbgFlow(D_HEALTH_CHECK_MANAGER) << "Sending a health check patch";
|
||||
|
||||
HealthCheckPatch patch_to_send(general_health_aggregated_status, all_comps_health_status);
|
||||
auto messaging = Singleton::Consume<I_Messaging>::by<HealthCheckManager>();
|
||||
return messaging->sendSyncMessageWithoutResponse(
|
||||
HealthCheckPatch patch_to_send(general_health_aggregated_status, health_check_reply);
|
||||
extended_status.clear();
|
||||
field_types_status.clear();
|
||||
return Singleton::Consume<I_Messaging>::by<HealthCheckManager>()->sendSyncMessageWithoutResponse(
|
||||
HTTPMethod::PATCH,
|
||||
"/agents",
|
||||
patch_to_send,
|
||||
@ -178,59 +238,11 @@ private:
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
getRegisteredComponentsHealthStatus()
|
||||
{
|
||||
vector<HealthCheckStatusReply> health_check_event_reply = HealthCheckStatusEvent().query();
|
||||
all_comps_health_status.clear();
|
||||
for (const auto &reply : health_check_event_reply) {
|
||||
if (reply.getStatus() != HealthCheckStatus::IGNORED) {
|
||||
all_comps_health_status.emplace(reply.getCompName(), reply);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
calcGeneralHealthAggregatedStatus()
|
||||
{
|
||||
general_health_aggregated_status = HealthCheckStatus::HEALTHY;
|
||||
|
||||
for (const auto &reply : all_comps_health_status) {
|
||||
HealthCheckStatus status = reply.second.getStatus();
|
||||
|
||||
dbgTrace(D_HEALTH_CHECK_MANAGER)
|
||||
<< "Current aggregated status is: "
|
||||
<< HealthCheckStatusReply::convertHealthCheckStatusToStr(
|
||||
general_health_aggregated_status
|
||||
)
|
||||
<< ". Got health status: "
|
||||
<< HealthCheckStatusReply::convertHealthCheckStatusToStr(status)
|
||||
<< "for component: "
|
||||
<< reply.first;
|
||||
|
||||
switch (status) {
|
||||
case HealthCheckStatus::UNHEALTHY : {
|
||||
general_health_aggregated_status = HealthCheckStatus::UNHEALTHY;
|
||||
return;
|
||||
}
|
||||
case HealthCheckStatus::DEGRADED : {
|
||||
general_health_aggregated_status = HealthCheckStatus::DEGRADED;
|
||||
break;
|
||||
}
|
||||
case HealthCheckStatus::IGNORED : break;
|
||||
case HealthCheckStatus::HEALTHY : break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
executeHealthCheck()
|
||||
{
|
||||
dbgFlow(D_HEALTH_CHECK_MANAGER) << "Collecting health status from all registered components.";
|
||||
|
||||
getRegisteredComponentsHealthStatus();
|
||||
calcGeneralHealthAggregatedStatus();
|
||||
|
||||
dbgTrace(D_HEALTH_CHECK_MANAGER)
|
||||
<< "Aggregated status: "
|
||||
<< HealthCheckStatusReply::convertHealthCheckStatusToStr(general_health_aggregated_status);
|
||||
@ -244,9 +256,43 @@ private:
|
||||
};
|
||||
}
|
||||
|
||||
HealthCheckStatus general_health_aggregated_status;
|
||||
map<string, HealthCheckStatusReply> all_comps_health_status;
|
||||
string
|
||||
convertOrchestrationStatusFieldTypeToStr(OrchestrationStatusFieldType type)
|
||||
{
|
||||
switch (type) {
|
||||
case OrchestrationStatusFieldType::REGISTRATION : return "Registration";
|
||||
case OrchestrationStatusFieldType::MANIFEST : return "Manifest";
|
||||
case OrchestrationStatusFieldType::LAST_UPDATE : return "Last Update";
|
||||
case OrchestrationStatusFieldType::COUNT : return "Count";
|
||||
}
|
||||
|
||||
dbgAssert(false) << "Trying to convert unknown orchestration status field to string.";
|
||||
return "";
|
||||
}
|
||||
|
||||
HealthCheckStatus
|
||||
convertResultToHealthCheckStatus(UpdatesProcessResult result)
|
||||
{
|
||||
switch (result) {
|
||||
case UpdatesProcessResult::SUCCESS : return HealthCheckStatus::HEALTHY;
|
||||
case UpdatesProcessResult::UNSET : return HealthCheckStatus::IGNORED;
|
||||
case UpdatesProcessResult::FAILED : return HealthCheckStatus::UNHEALTHY;
|
||||
case UpdatesProcessResult::DEGRADED : return HealthCheckStatus::DEGRADED;
|
||||
}
|
||||
|
||||
dbgAssert(false) << "Trying to convert unknown update process result field to health check status.";
|
||||
return HealthCheckStatus::IGNORED;
|
||||
}
|
||||
|
||||
HealthCheckStatus general_health_aggregated_status = HealthCheckStatus::HEALTHY;
|
||||
HealthCheckStatusReply health_check_reply = HealthCheckStatusReply(
|
||||
"Orchestration",
|
||||
HealthCheckStatus::HEALTHY,
|
||||
{}
|
||||
);
|
||||
bool should_patch_report;
|
||||
map<string, string> extended_status;
|
||||
map<string, HealthCheckStatus> field_types_status;
|
||||
};
|
||||
|
||||
HealthCheckManager::HealthCheckManager() : Component("HealthCheckManager"), pimpl(make_unique<Impl>()) {}
|
@ -4,5 +4,5 @@ link_directories(${BOOST_ROOT}/lib)
|
||||
add_unit_test(
|
||||
health_check_manager_ut
|
||||
"health_check_manager_ut.cc"
|
||||
"singleton;messaging;mainloop;health_check_manager;event_is;metric;-lboost_regex"
|
||||
"singleton;updates_process_reporter;messaging;mainloop;health_check_manager;event_is;metric;-lboost_regex"
|
||||
)
|
@ -13,42 +13,13 @@
|
||||
#include "mock/mock_mainloop.h"
|
||||
#include "mock/mock_messaging.h"
|
||||
#include "mock/mock_rest_api.h"
|
||||
#include "updates_process_event.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace testing;
|
||||
|
||||
USE_DEBUG_FLAG(D_HEALTH_CHECK);
|
||||
|
||||
class TestHealthCheckStatusListener : public Listener<HealthCheckStatusEvent>
|
||||
{
|
||||
public:
|
||||
void upon(const HealthCheckStatusEvent &) override {}
|
||||
|
||||
HealthCheckStatusReply
|
||||
respond(const HealthCheckStatusEvent &) override
|
||||
{
|
||||
map<string, string> extended_status;
|
||||
extended_status["team"] = team;
|
||||
extended_status["city"] = city;
|
||||
HealthCheckStatusReply reply(comp_name, status, extended_status);
|
||||
return reply;
|
||||
}
|
||||
|
||||
void setStatus(HealthCheckStatus new_status) { status = new_status; }
|
||||
|
||||
string getListenerName() const { return "TestHealthCheckStatusListener"; }
|
||||
|
||||
private:
|
||||
static const string comp_name;
|
||||
HealthCheckStatus status = HealthCheckStatus::HEALTHY;
|
||||
static const string team;
|
||||
static const string city;
|
||||
};
|
||||
|
||||
const string TestHealthCheckStatusListener::comp_name = "Test";
|
||||
const string TestHealthCheckStatusListener::team = "Hapoel";
|
||||
const string TestHealthCheckStatusListener::city = "Tel-Aviv";
|
||||
|
||||
class TestEnd {};
|
||||
|
||||
class HealthCheckManagerTest : public Test
|
||||
@ -56,8 +27,7 @@ class HealthCheckManagerTest : public Test
|
||||
public:
|
||||
HealthCheckManagerTest()
|
||||
{
|
||||
Debug::setNewDefaultStdout(&debug_output);
|
||||
Debug::setUnitTestFlag(D_HEALTH_CHECK, Debug::DebugLevel::INFO);
|
||||
Debug::setUnitTestFlag(D_HEALTH_CHECK, Debug::DebugLevel::NOISE);
|
||||
|
||||
EXPECT_CALL(mock_ml, addRecurringRoutine(_, _, _, _, _)).WillRepeatedly(
|
||||
DoAll(SaveArg<2>(&health_check_periodic_routine), Return(1))
|
||||
@ -70,7 +40,6 @@ public:
|
||||
);
|
||||
|
||||
env.preload();
|
||||
event_listener.registerListener();
|
||||
|
||||
env.init();
|
||||
|
||||
@ -98,14 +67,12 @@ public:
|
||||
StrictMock<MockMainLoop> mock_ml;
|
||||
StrictMock<MockRestApi> mock_rest;
|
||||
StrictMock<MockMessaging> mock_message;
|
||||
stringstream debug_output;
|
||||
ConfigComponent config;
|
||||
Config::I_Config *i_config = nullptr;
|
||||
::Environment env;
|
||||
HealthCheckManager health_check_manager;
|
||||
I_Health_Check_Manager *i_health_check_manager;
|
||||
unique_ptr<ServerRest> health_check_server;
|
||||
TestHealthCheckStatusListener event_listener;
|
||||
};
|
||||
|
||||
TEST_F(HealthCheckManagerTest, runPeriodicHealthCheckTest)
|
||||
@ -142,7 +109,20 @@ TEST_F(HealthCheckManagerTest, runPeriodicHealthCheckTest)
|
||||
EXPECT_EQ(actual_body, expected_healthy_body);
|
||||
EXPECT_EQ("Healthy", aggregated_status_str);
|
||||
|
||||
event_listener.setStatus(HealthCheckStatus::DEGRADED);
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::DEGRADED,
|
||||
UpdatesConfigType::SETTINGS,
|
||||
UpdatesFailureReason::DOWNLOAD_FILE,
|
||||
"setting.json",
|
||||
"File not found"
|
||||
).notify();
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::DEGRADED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::DOWNLOAD_FILE,
|
||||
"manifest.json",
|
||||
"File not found"
|
||||
).notify();
|
||||
try {
|
||||
health_check_periodic_routine();
|
||||
} catch (const TestEnd &t) {}
|
||||
@ -156,16 +136,16 @@ TEST_F(HealthCheckManagerTest, runPeriodicHealthCheckTest)
|
||||
" \"status\": \"Degraded\",\n"
|
||||
" \"errors\": [\n"
|
||||
" {\n"
|
||||
" \"code\": \"Test city\",\n"
|
||||
" \"code\": \"Orchestration Last Update\",\n"
|
||||
" \"message\": [\n"
|
||||
" \"Tel-Aviv\"\n"
|
||||
" \"Failed to download the file setting.json. Error: File not found\"\n"
|
||||
" ],\n"
|
||||
" \"internal\": true\n"
|
||||
" },\n"
|
||||
" {\n"
|
||||
" \"code\": \"Test team\",\n"
|
||||
" \"code\": \"Orchestration Manifest\",\n"
|
||||
" \"message\": [\n"
|
||||
" \"Hapoel\"\n"
|
||||
" \"Failed to download the file manifest.json. Error: File not found\"\n"
|
||||
" ],\n"
|
||||
" \"internal\": true\n"
|
||||
" }\n"
|
||||
@ -196,19 +176,24 @@ TEST_F(HealthCheckManagerTest, runOnDemandHealthCheckTest)
|
||||
config.preload();
|
||||
Singleton::Consume<Config::I_Config>::from(config)->loadConfiguration(ss);
|
||||
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::DOWNLOAD_FILE,
|
||||
"manifest.json",
|
||||
"File not found"
|
||||
).notify();
|
||||
|
||||
stringstream is;
|
||||
is << "{}";
|
||||
health_check_server->performRestCall(is);
|
||||
|
||||
string expected_status =
|
||||
"{\n"
|
||||
" \"allComponentsHealthCheckReplies\": {\n"
|
||||
" \"Test\": {\n"
|
||||
" \"status\": \"Healthy\",\n"
|
||||
" \"extendedStatus\": {\n"
|
||||
" \"city\": \"Tel-Aviv\",\n"
|
||||
" \"team\": \"Hapoel\"\n"
|
||||
" }\n"
|
||||
" \"Orchestration\": {\n"
|
||||
" \"status\": \"Unhealthy\",\n"
|
||||
" \"extendedStatus\": {\n"
|
||||
" \"Manifest\": \"Failed to download the file manifest.json. Error: File not found\"\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}";
|
@ -0,0 +1,130 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __UPDATES_PROCESS_EVENT_H__
|
||||
#define __UPDATES_PROCESS_EVENT_H__
|
||||
|
||||
#include "event.h"
|
||||
#include "singleton.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "i_orchestration_status.h"
|
||||
#include "health_check_status/health_check_status.h"
|
||||
#include "customized_cereal_map.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_UPDATES_PROCESS_REPORTER);
|
||||
|
||||
enum class UpdatesFailureReason {
|
||||
CHECK_UPDATE,
|
||||
REGISTRATION,
|
||||
ORCHESTRATION_SELF_UPDATE,
|
||||
GET_UPDATE_REQUEST,
|
||||
DOWNLOAD_FILE,
|
||||
HANDLE_FILE,
|
||||
INSTALLATION_QUEUE,
|
||||
INSTALL_PACKAGE,
|
||||
CHECKSUM_UNMATCHED,
|
||||
POLICY_CONFIGURATION,
|
||||
POLICY_FOG_CONFIGURATION,
|
||||
NONE
|
||||
|
||||
};
|
||||
|
||||
enum class UpdatesConfigType { MANIFEST, POLICY, SETTINGS, DATA, GENERAL };
|
||||
enum class UpdatesProcessResult { UNSET, SUCCESS, FAILED, DEGRADED };
|
||||
|
||||
static inline std::string
|
||||
convertUpdatesFailureReasonToStr(UpdatesFailureReason reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case UpdatesFailureReason::CHECK_UPDATE : return "CHECK_UPDATE";
|
||||
case UpdatesFailureReason::REGISTRATION : return "REGISTRATION";
|
||||
case UpdatesFailureReason::ORCHESTRATION_SELF_UPDATE : return "ORCHESTRATION_SELF_UPDATE";
|
||||
case UpdatesFailureReason::GET_UPDATE_REQUEST : return "GET_UPDATE_REQUEST";
|
||||
case UpdatesFailureReason::DOWNLOAD_FILE : return "DOWNLOAD_FILE";
|
||||
case UpdatesFailureReason::HANDLE_FILE : return "HANDLE_FILE";
|
||||
case UpdatesFailureReason::INSTALLATION_QUEUE : return "INSTALLATION_QUEUE";
|
||||
case UpdatesFailureReason::INSTALL_PACKAGE : return "INSTALL_PACKAGE";
|
||||
case UpdatesFailureReason::CHECKSUM_UNMATCHED : return "CHECKSUM_UNMATCHED";
|
||||
case UpdatesFailureReason::POLICY_CONFIGURATION : return "POLICY_CONFIGURATION";
|
||||
case UpdatesFailureReason::POLICY_FOG_CONFIGURATION : return "POLICY_FOG_CONFIGURATION";
|
||||
case UpdatesFailureReason::NONE : return "NONE";
|
||||
}
|
||||
|
||||
dbgWarning(D_UPDATES_PROCESS_REPORTER) << "Trying to convert unknown updates failure reason to string.";
|
||||
return "";
|
||||
}
|
||||
|
||||
static inline std::string
|
||||
convertUpdatesConfigTypeToStr(UpdatesConfigType type)
|
||||
{
|
||||
switch (type) {
|
||||
case UpdatesConfigType::MANIFEST : return "MANIFEST";
|
||||
case UpdatesConfigType::POLICY : return "POLICY";
|
||||
case UpdatesConfigType::SETTINGS : return "SETTINGS";
|
||||
case UpdatesConfigType::DATA : return "DATA";
|
||||
case UpdatesConfigType::GENERAL : return "GENERAL";
|
||||
}
|
||||
|
||||
dbgWarning(D_UPDATES_PROCESS_REPORTER) << "Trying to convert unknown updates failure reason to string.";
|
||||
return "";
|
||||
}
|
||||
|
||||
static inline std::string
|
||||
convertUpdateProcessResultToStr(UpdatesProcessResult result)
|
||||
{
|
||||
switch (result) {
|
||||
case UpdatesProcessResult::SUCCESS : return "SUCCESS";
|
||||
case UpdatesProcessResult::UNSET : return "UNSET";
|
||||
case UpdatesProcessResult::FAILED : return "FAILURE";
|
||||
case UpdatesProcessResult::DEGRADED : return "DEGRADED";
|
||||
}
|
||||
|
||||
dbgWarning(D_UPDATES_PROCESS_REPORTER) << "Trying to convert unknown updates failure reason to string.";
|
||||
return "";
|
||||
}
|
||||
|
||||
class UpdatesProcessEvent : public Event<UpdatesProcessEvent>
|
||||
{
|
||||
public:
|
||||
UpdatesProcessEvent() {}
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult _result,
|
||||
UpdatesConfigType _type,
|
||||
UpdatesFailureReason _reason = UpdatesFailureReason::NONE,
|
||||
const std::string &_detail = "",
|
||||
const std::string &_description = "");
|
||||
|
||||
~UpdatesProcessEvent() {}
|
||||
|
||||
UpdatesProcessResult getResult() const { return result; }
|
||||
UpdatesConfigType getType() const { return type; }
|
||||
UpdatesFailureReason getReason() const { return reason; }
|
||||
std::string getDetail() const { return detail; }
|
||||
std::string getDescription() const { return description; }
|
||||
|
||||
OrchestrationStatusFieldType getStatusFieldType() const;
|
||||
OrchestrationStatusResult getOrchestrationStatusResult() const;
|
||||
|
||||
std::string parseDescription() const;
|
||||
|
||||
private:
|
||||
UpdatesProcessResult result;
|
||||
UpdatesConfigType type;
|
||||
UpdatesFailureReason reason;
|
||||
std::string detail;
|
||||
std::string description;
|
||||
|
||||
};
|
||||
|
||||
#endif // __UPDATES_PROCESS_EVENT_H__
|
@ -0,0 +1,61 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __UPDATES_PROCESS_REPORT_H__
|
||||
#define __UPDATES_PROCESS_REPORT_H__
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "singleton.h"
|
||||
#include "i_time_get.h"
|
||||
#include "updates_process_event.h"
|
||||
|
||||
class UpdatesProcessReport : Singleton::Consume<I_TimeGet>
|
||||
{
|
||||
public:
|
||||
UpdatesProcessReport(
|
||||
UpdatesProcessResult result,
|
||||
UpdatesConfigType type,
|
||||
UpdatesFailureReason reason,
|
||||
const std::string &description)
|
||||
:
|
||||
result(result), type(type), reason(reason), description(description)
|
||||
{
|
||||
time_stamp = Singleton::Consume<I_TimeGet>::by<UpdatesProcessReport>()->getWalltimeStr();
|
||||
}
|
||||
|
||||
std::string
|
||||
toString() const
|
||||
{
|
||||
std::stringstream report;
|
||||
report
|
||||
<< "["
|
||||
<< time_stamp << "] - "
|
||||
<< convertUpdateProcessResultToStr(result) << " | "
|
||||
<< convertUpdatesConfigTypeToStr(type) << " | "
|
||||
<< convertUpdatesFailureReasonToStr(reason) << " | "
|
||||
<< description;
|
||||
|
||||
return report.str();
|
||||
}
|
||||
|
||||
private:
|
||||
UpdatesProcessResult result;
|
||||
UpdatesConfigType type;
|
||||
UpdatesFailureReason reason;
|
||||
std::string description;
|
||||
std::string time_stamp;
|
||||
};
|
||||
|
||||
#endif // __UPDATES_PROCESS_EVENT_H__
|
@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __UPDATES_PROCESS_REPORTER_H__
|
||||
#define __UPDATES_PROCESS_REPORTER_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "event.h"
|
||||
#include "singleton.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "i_orchestration_status.h"
|
||||
#include "health_check_status/health_check_status.h"
|
||||
#include "updates_process_event.h"
|
||||
#include "updates_process_report.h"
|
||||
|
||||
class UpdatesProcessReporter : public Listener<UpdatesProcessEvent>
|
||||
{
|
||||
public:
|
||||
void upon(const UpdatesProcessEvent &event) override;
|
||||
|
||||
private:
|
||||
void sendReoprt();
|
||||
|
||||
static std::vector<UpdatesProcessReport> reports;
|
||||
};
|
||||
|
||||
#endif // __UPDATES_PROCESS_REPORTER_H__
|
@ -21,6 +21,7 @@
|
||||
#include "version.h"
|
||||
#include "log_generator.h"
|
||||
#include "orchestration_comp.h"
|
||||
#include "updates_process_event.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ReportIS;
|
||||
@ -219,6 +220,13 @@ ManifestController::Impl::updateManifest(const string &new_manifest_file)
|
||||
if (isIgnoreFile(new_manifest_file)) {
|
||||
if (!orchestration_tools->copyFile(new_manifest_file, manifest_file_path)) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to copy a new manifest file";
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::HANDLE_FILE,
|
||||
new_manifest_file,
|
||||
"Failed to copy a new manifest file"
|
||||
).notify();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -237,6 +245,13 @@ ManifestController::Impl::updateManifest(const string &new_manifest_file)
|
||||
|
||||
if (!orchestration_tools->copyFile(new_manifest_file, manifest_file_path)) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to copy a new manifest file";
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::HANDLE_FILE,
|
||||
new_manifest_file,
|
||||
"Failed to copy a new manifest file"
|
||||
).notify();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -245,6 +260,13 @@ ManifestController::Impl::updateManifest(const string &new_manifest_file)
|
||||
Maybe<map<string, Package>> parsed_manifest = orchestration_tools->loadPackagesFromJson(new_manifest_file);
|
||||
if (!parsed_manifest.ok()) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to parse the new manifest file. File: " << new_manifest_file;
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::HANDLE_FILE,
|
||||
new_manifest_file,
|
||||
"Failed to parse the new manifest file"
|
||||
).notify();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -332,6 +354,13 @@ ManifestController::Impl::updateManifest(const string &new_manifest_file)
|
||||
dbgWarning(D_ORCHESTRATOR)
|
||||
<< "Failed building installation queue. Error: "
|
||||
<< installation_queue_res.getErr();
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::INSTALLATION_QUEUE,
|
||||
"",
|
||||
installation_queue_res.getErr()
|
||||
).notify();
|
||||
return false;
|
||||
}
|
||||
const vector<Package> &installation_queue = installation_queue_res.unpack();
|
||||
@ -447,11 +476,25 @@ ManifestController::Impl::changeManifestFile(const string &new_manifest_file)
|
||||
dbgDebug(D_ORCHESTRATOR) << "Writing new manifest to file";
|
||||
if (!orchestration_tools->copyFile(new_manifest_file, manifest_file_path)) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed write new manifest to file";
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::HANDLE_FILE,
|
||||
new_manifest_file,
|
||||
"Failed write new manifest to file"
|
||||
).notify();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!orchestration_tools->isNonEmptyFile(manifest_file_path)) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to get manifest file data";
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::HANDLE_FILE,
|
||||
manifest_file_path,
|
||||
"Failed to get manifest file data"
|
||||
).notify();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -281,13 +281,7 @@ TEST_F(ManifestControllerTest, badChecksum)
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist("/etc/cp/packages/my/my")).WillOnce(Return(false));
|
||||
|
||||
string hostname = "hostname";
|
||||
string empty_err;
|
||||
EXPECT_CALL(mock_status, getManifestError()).WillOnce(ReturnRef(empty_err));
|
||||
EXPECT_CALL(mock_details_resolver, getHostname()).WillOnce(Return( Maybe<string>(hostname)));
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::MANIFEST, OrchestrationStatusResult::FAILED, _)
|
||||
);
|
||||
EXPECT_FALSE(i_manifest_controller->updateManifest(file_name));
|
||||
}
|
||||
|
||||
@ -710,10 +704,6 @@ TEST_F(ManifestControllerTest, selfUpdateWithOldCopyWithError)
|
||||
string hostname = "hostname";
|
||||
string empty_err;
|
||||
EXPECT_CALL(mock_status, getManifestError()).WillOnce(ReturnRef(empty_err));
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::MANIFEST, OrchestrationStatusResult::FAILED, _)
|
||||
);
|
||||
load(manifest, new_services);
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools,
|
||||
@ -932,10 +922,6 @@ TEST_F(ManifestControllerTest, badInstall)
|
||||
string empty_err;
|
||||
EXPECT_CALL(mock_status, getManifestError()).WillOnce(ReturnRef(empty_err));
|
||||
EXPECT_CALL(mock_details_resolver, getHostname()).WillOnce(Return( Maybe<string>(hostname)));
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::MANIFEST, OrchestrationStatusResult::FAILED, _)
|
||||
);
|
||||
|
||||
string corrupted_packages_manifest =
|
||||
"{"
|
||||
@ -1008,12 +994,6 @@ TEST_F(ManifestControllerTest, failToDownloadWithselfUpdate)
|
||||
doesFileExist("/etc/cp/packages/orchestration/orchestration")
|
||||
).WillOnce(Return(false));
|
||||
EXPECT_CALL(mock_details_resolver, getHostname()).WillOnce(Return(string("hostname")));
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::MANIFEST, OrchestrationStatusResult::FAILED, _)
|
||||
);
|
||||
string not_error;
|
||||
EXPECT_CALL(mock_status, getManifestError()).WillOnce(ReturnRef(not_error));
|
||||
EXPECT_FALSE(i_manifest_controller->updateManifest(file_name));
|
||||
}
|
||||
|
||||
@ -1404,12 +1384,6 @@ TEST_F(ManifestControllerTest, failureOnDownloadSharedObject)
|
||||
).WillOnce(Return(false));
|
||||
EXPECT_CALL(mock_details_resolver, getHostname()).WillOnce(Return(string("hostname")));
|
||||
EXPECT_CALL(mock_orchestration_tools, removeFile("/tmp/temp_file1")).WillOnce(Return(true));
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::MANIFEST, OrchestrationStatusResult::FAILED, _)
|
||||
);
|
||||
string not_error;
|
||||
EXPECT_CALL(mock_status, getManifestError()).WillOnce(ReturnRef(not_error));
|
||||
|
||||
EXPECT_FALSE(i_manifest_controller->updateManifest(file_name));
|
||||
}
|
||||
@ -2538,12 +2512,6 @@ TEST_F(ManifestDownloadTest, download_relative_path)
|
||||
doesFileExist("/etc/cp/packages/orchestration/orchestration")
|
||||
).WillOnce(Return(false));
|
||||
EXPECT_CALL(mock_details_resolver, getHostname()).WillOnce(Return(string("hostname")));
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::MANIFEST, OrchestrationStatusResult::FAILED, _)
|
||||
);
|
||||
string not_error;
|
||||
EXPECT_CALL(mock_status, getManifestError()).WillOnce(ReturnRef(not_error));
|
||||
|
||||
EXPECT_FALSE(i_manifest_controller->updateManifest(manifest_file.fname));
|
||||
}
|
||||
@ -2589,8 +2557,6 @@ TEST_F(ManifestDownloadTest, download_relative_path_no_fog_domain)
|
||||
mock_orchestration_tools,
|
||||
doesFileExist("/etc/cp/packages/orchestration/orchestration")
|
||||
).WillOnce(Return(false));
|
||||
string not_error;
|
||||
EXPECT_CALL(mock_status, getManifestError()).WillOnce(ReturnRef(not_error));
|
||||
|
||||
checkIfFileExistsCall(new_packages.at("orchestration"));
|
||||
|
||||
@ -2604,10 +2570,6 @@ TEST_F(ManifestDownloadTest, download_relative_path_no_fog_domain)
|
||||
)
|
||||
).WillOnce(Return(downloaded_package));
|
||||
EXPECT_CALL(mock_details_resolver, getHostname()).WillOnce(Return(string("hostname")));
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::MANIFEST, OrchestrationStatusResult::FAILED, _)
|
||||
);
|
||||
|
||||
EXPECT_FALSE(i_manifest_controller->updateManifest(manifest_file.fname));
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "config.h"
|
||||
#include "agent_details.h"
|
||||
#include "orchestration_comp.h"
|
||||
#include "updates_process_event.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -174,14 +175,13 @@ ManifestHandler::downloadPackages(const map<string, Package> &new_packages_to_do
|
||||
" software update failed. Agent is running previous software. Contact Check Point support.";
|
||||
}
|
||||
|
||||
auto orchestration_status = Singleton::Consume<I_OrchestrationStatus>::by<ManifestHandler>();
|
||||
if (orchestration_status->getManifestError().find("Gateway was not fully deployed") == string::npos) {
|
||||
orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::MANIFEST,
|
||||
OrchestrationStatusResult::FAILED,
|
||||
install_error
|
||||
);
|
||||
}
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::DOWNLOAD_FILE,
|
||||
package.getName(),
|
||||
install_error
|
||||
).notify();
|
||||
return genError(
|
||||
"Failed to download installation package. Package: " +
|
||||
package.getName() +
|
||||
@ -219,11 +219,13 @@ ManifestHandler::installPackage(
|
||||
err_hostname +
|
||||
" software update failed. Agent is running previous software. Contact Check Point support.";
|
||||
if (orchestration_status->getManifestError().find("Gateway was not fully deployed") == string::npos) {
|
||||
orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::MANIFEST,
|
||||
OrchestrationStatusResult::FAILED,
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::INSTALL_PACKAGE,
|
||||
package_name,
|
||||
install_error
|
||||
);
|
||||
).notify();
|
||||
}
|
||||
}
|
||||
return self_update_status;
|
||||
@ -289,11 +291,13 @@ ManifestHandler::installPackage(
|
||||
|
||||
auto orchestration_status = Singleton::Consume<I_OrchestrationStatus>::by<ManifestHandler>();
|
||||
if (orchestration_status->getManifestError().find("Gateway was not fully deployed") == string::npos) {
|
||||
orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::MANIFEST,
|
||||
OrchestrationStatusResult::FAILED,
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::INSTALL_PACKAGE,
|
||||
package_name,
|
||||
install_error
|
||||
);
|
||||
).notify();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "mock/mock_agent_details.h"
|
||||
#include "mock/mock_mainloop.h"
|
||||
#include "mock/mock_rest_api.h"
|
||||
#include "updates_process_event.h"
|
||||
|
||||
using namespace testing;
|
||||
using namespace std;
|
||||
@ -200,6 +201,19 @@ TEST_F(OrchestrationStatusTest, checkUpdateStatus)
|
||||
auto result = orchestrationStatusFileToString();
|
||||
EXPECT_EQ(buildOrchestrationStatusJSON("attempt time", "Succeeded ", "current time"), result);
|
||||
}
|
||||
TEST_F(OrchestrationStatusTest, checkUpdateStatusByRaiseEvent)
|
||||
{
|
||||
init();
|
||||
EXPECT_CALL(time, getLocalTimeStr())
|
||||
.WillOnce(Return(string("attempt time")))
|
||||
.WillOnce(Return(string("current time")));
|
||||
|
||||
i_orchestration_status->setLastUpdateAttempt();
|
||||
|
||||
UpdatesProcessEvent(UpdatesProcessResult::SUCCESS, UpdatesConfigType::GENERAL).notify();
|
||||
auto result = orchestrationStatusFileToString();
|
||||
EXPECT_EQ(buildOrchestrationStatusJSON("attempt time", "Succeeded ", "current time"), result);
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationStatusTest, recoveryFields)
|
||||
{
|
||||
@ -482,3 +496,69 @@ TEST_F(OrchestrationStatusTest, setAllFields)
|
||||
EXPECT_EQ(i_orchestration_status->getServiceSettings(), service_map_a);
|
||||
EXPECT_EQ(i_orchestration_status->getRegistrationDetails(), agent_details);
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationStatusTest, checkErrorByRaiseEvent)
|
||||
{
|
||||
init();
|
||||
string fog_address = "http://fog.address";
|
||||
string registar_error = "Fail to registar";
|
||||
string manifest_error = "Fail to achieve manifest";
|
||||
string last_update_error = "Fail to update";
|
||||
|
||||
EXPECT_CALL(time, getLocalTimeStr()).Times(3).WillRepeatedly(Return(string("Time")));
|
||||
|
||||
UpdatesProcessEvent(UpdatesProcessResult::SUCCESS, UpdatesConfigType::GENERAL).notify();
|
||||
i_orchestration_status->setIsConfigurationUpdated(
|
||||
EnumArray<OrchestrationStatusConfigType, bool>(true, true, true)
|
||||
);
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::GENERAL,
|
||||
UpdatesFailureReason::NONE,
|
||||
"",
|
||||
last_update_error
|
||||
).notify();
|
||||
i_orchestration_status->setIsConfigurationUpdated(
|
||||
EnumArray<OrchestrationStatusConfigType, bool>(false, false, false)
|
||||
);
|
||||
|
||||
i_orchestration_status->setUpgradeMode("Online upgrades");
|
||||
i_orchestration_status->setFogAddress(fog_address);
|
||||
|
||||
i_orchestration_status->setUpgradeMode("Online upgrades");
|
||||
i_orchestration_status->setFogAddress(fog_address);
|
||||
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::GENERAL,
|
||||
UpdatesFailureReason::REGISTRATION,
|
||||
"",
|
||||
registar_error
|
||||
).notify();
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::NONE,
|
||||
"",
|
||||
manifest_error
|
||||
).notify();
|
||||
EXPECT_EQ(i_orchestration_status->getManifestError(), manifest_error);
|
||||
|
||||
auto result = orchestrationStatusFileToString();
|
||||
EXPECT_EQ(
|
||||
buildOrchestrationStatusJSON(
|
||||
"None",
|
||||
"Failed. Reason: " + last_update_error,
|
||||
"Time",
|
||||
"Time",
|
||||
"",
|
||||
"Time",
|
||||
"Time",
|
||||
"Online upgrades",
|
||||
fog_address,
|
||||
"Failed. Reason: Registration failed. Error: " + registar_error,
|
||||
"Failed. Reason: " + manifest_error
|
||||
),
|
||||
result
|
||||
);
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include "debug.h"
|
||||
#include "config.h"
|
||||
#include "updates_process_event.h"
|
||||
#include "health_check_status/health_check_status.h"
|
||||
|
||||
using namespace cereal;
|
||||
using namespace std;
|
||||
@ -383,7 +385,10 @@ private:
|
||||
map<string, string> service_settings;
|
||||
};
|
||||
|
||||
class OrchestrationStatus::Impl : Singleton::Provide<I_OrchestrationStatus>::From<OrchestrationStatus>
|
||||
class OrchestrationStatus::Impl
|
||||
:
|
||||
Singleton::Provide<I_OrchestrationStatus>::From<OrchestrationStatus>,
|
||||
public Listener<UpdatesProcessEvent>
|
||||
{
|
||||
public:
|
||||
void
|
||||
@ -462,6 +467,13 @@ public:
|
||||
},
|
||||
"Write Orchestration status file"
|
||||
);
|
||||
registerListener();
|
||||
}
|
||||
|
||||
void
|
||||
upon(const UpdatesProcessEvent &event) override
|
||||
{
|
||||
setFieldStatus(event.getStatusFieldType(), event.getOrchestrationStatusResult(), event.parseDescription());
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -42,6 +42,8 @@
|
||||
#include "hybrid_communication.h"
|
||||
#include "agent_core_utilities.h"
|
||||
#include "fog_communication.h"
|
||||
#include "updates_process_event.h"
|
||||
#include "updates_process_reporter.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace chrono;
|
||||
@ -53,85 +55,6 @@ USE_DEBUG_FLAG(D_ORCHESTRATOR);
|
||||
static string fw_last_update_time = "";
|
||||
#endif // gaia || smb
|
||||
|
||||
class HealthCheckStatusListener : public Listener<HealthCheckStatusEvent>
|
||||
{
|
||||
public:
|
||||
void upon(const HealthCheckStatusEvent &) override {}
|
||||
|
||||
HealthCheckStatusReply
|
||||
respond(const HealthCheckStatusEvent &) override
|
||||
{
|
||||
return HealthCheckStatusReply(comp_name, status, extended_status);
|
||||
}
|
||||
|
||||
string getListenerName() const override { return "HealthCheckStatusListener"; }
|
||||
|
||||
void
|
||||
setStatus(
|
||||
HealthCheckStatus _status,
|
||||
OrchestrationStatusFieldType _status_field_type,
|
||||
const string &_status_description = "Success")
|
||||
{
|
||||
string status_field_type_str = convertOrchestrationStatusFieldTypeToStr(_status_field_type);
|
||||
extended_status[status_field_type_str] = _status_description;
|
||||
field_types_status[status_field_type_str] = _status;
|
||||
|
||||
switch(_status) {
|
||||
case HealthCheckStatus::UNHEALTHY: {
|
||||
status = HealthCheckStatus::UNHEALTHY;
|
||||
return;
|
||||
}
|
||||
case HealthCheckStatus::DEGRADED: {
|
||||
for (const auto &type_status : field_types_status) {
|
||||
if ((type_status.first != status_field_type_str)
|
||||
&& (type_status.second == HealthCheckStatus::UNHEALTHY))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
status = HealthCheckStatus::DEGRADED;
|
||||
return;
|
||||
}
|
||||
case HealthCheckStatus::HEALTHY: {
|
||||
for (const auto &type_status : field_types_status) {
|
||||
if ((type_status.first != status_field_type_str)
|
||||
&& (type_status.second == HealthCheckStatus::UNHEALTHY
|
||||
|| type_status.second == HealthCheckStatus::DEGRADED)
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
status = HealthCheckStatus::HEALTHY;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case HealthCheckStatus::IGNORED: {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
string
|
||||
convertOrchestrationStatusFieldTypeToStr(OrchestrationStatusFieldType type)
|
||||
{
|
||||
switch (type) {
|
||||
case OrchestrationStatusFieldType::REGISTRATION : return "Registration";
|
||||
case OrchestrationStatusFieldType::MANIFEST : return "Manifest";
|
||||
case OrchestrationStatusFieldType::LAST_UPDATE : return "Last Update";
|
||||
case OrchestrationStatusFieldType::COUNT : return "Count";
|
||||
}
|
||||
|
||||
dbgError(D_ORCHESTRATOR) << "Trying to convert unknown orchestration status field to string.";
|
||||
return "";
|
||||
}
|
||||
|
||||
string comp_name = "Orchestration";
|
||||
HealthCheckStatus status = HealthCheckStatus::IGNORED;
|
||||
map<string, string> extended_status;
|
||||
map<string, HealthCheckStatus> field_types_status;
|
||||
};
|
||||
|
||||
class SetAgentUninstall
|
||||
:
|
||||
public ServerRest,
|
||||
@ -257,6 +180,13 @@ private:
|
||||
<< "Failed to load Orchestration Policy. Error: "
|
||||
<< maybe_policy.getErr()
|
||||
<< "Trying to load from backup.";
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::POLICY,
|
||||
UpdatesFailureReason::POLICY_CONFIGURATION,
|
||||
orchestration_policy_file,
|
||||
maybe_policy.getErr()
|
||||
).notify();
|
||||
return loadOrchestrationPolicyFromBackup();
|
||||
}
|
||||
|
||||
@ -280,6 +210,13 @@ private:
|
||||
return maybe_policy;
|
||||
}
|
||||
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::POLICY,
|
||||
UpdatesFailureReason::POLICY_CONFIGURATION,
|
||||
orchestration_policy_file + backup_ext,
|
||||
maybe_policy.getErr()
|
||||
).notify();
|
||||
return genError("Failed to load Orchestration policy from backup.");
|
||||
}
|
||||
|
||||
@ -337,17 +274,13 @@ private:
|
||||
<< new_manifest_file.getErr()
|
||||
<< " Presenting the next message to the user: "
|
||||
<< install_error;
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::MANIFEST,
|
||||
OrchestrationStatusResult::FAILED,
|
||||
install_error
|
||||
);
|
||||
|
||||
health_check_status_listener.setStatus(
|
||||
HealthCheckStatus::UNHEALTHY,
|
||||
OrchestrationStatusFieldType::MANIFEST,
|
||||
install_error
|
||||
);
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::DOWNLOAD_FILE,
|
||||
resource_file.getFileName(),
|
||||
new_manifest_file.getErr()
|
||||
).notify();
|
||||
|
||||
return genError(install_error);
|
||||
}
|
||||
@ -372,23 +305,12 @@ private:
|
||||
<< "Manifest failed to be updated. Presenting the next message to the user: "
|
||||
<< install_error;
|
||||
|
||||
health_check_status_listener.setStatus(
|
||||
HealthCheckStatus::UNHEALTHY,
|
||||
OrchestrationStatusFieldType::MANIFEST,
|
||||
install_error
|
||||
);
|
||||
|
||||
return genError(install_error);
|
||||
}
|
||||
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::MANIFEST,
|
||||
OrchestrationStatusResult::SUCCESS
|
||||
);
|
||||
health_check_status_listener.setStatus(
|
||||
HealthCheckStatus::HEALTHY,
|
||||
OrchestrationStatusFieldType::MANIFEST
|
||||
);
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::SUCCESS,
|
||||
UpdatesConfigType::MANIFEST
|
||||
).notify();
|
||||
|
||||
ifstream restart_watchdog_orch(filesystem_prefix + "/orchestration/restart_watchdog");
|
||||
if (restart_watchdog_orch.good()) {
|
||||
@ -473,6 +395,13 @@ private:
|
||||
if (!updateFogAddress(policy.getFogAddress())) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to restore the old Fog address.";
|
||||
}
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::POLICY,
|
||||
UpdatesFailureReason::POLICY_FOG_CONFIGURATION,
|
||||
orchestration_policy.getFogAddress(),
|
||||
"Failed to update the new Fog address."
|
||||
).notify();
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -499,13 +428,19 @@ private:
|
||||
// Handling policy update.
|
||||
dbgInfo(D_ORCHESTRATOR) << "There is a new policy file.";
|
||||
GetResourceFile resource_file(GetResourceFile::ResourceFileType::POLICY);
|
||||
Maybe<string> new_policy_file =
|
||||
Singleton::Consume<I_Downloader>::by<OrchestrationComp>()->downloadFile(
|
||||
Maybe<string> new_policy_file = Singleton::Consume<I_Downloader>::by<OrchestrationComp>()->downloadFile(
|
||||
new_policy.unpack(),
|
||||
I_OrchestrationTools::SELECTED_CHECKSUM_TYPE,
|
||||
resource_file
|
||||
);
|
||||
if (!new_policy_file.ok()) {
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::POLICY,
|
||||
UpdatesFailureReason::DOWNLOAD_FILE,
|
||||
resource_file.getFileName(),
|
||||
new_policy_file.getErr()
|
||||
).notify();
|
||||
return genError("Failed to download the new policy file. Error: " + new_policy_file.getErr());
|
||||
}
|
||||
|
||||
@ -564,6 +499,13 @@ private:
|
||||
<< LogField("policyVersion", updated_policy_version)
|
||||
<< LogField("previousPolicyVersion", old_policy_version);
|
||||
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::POLICY,
|
||||
UpdatesFailureReason::POLICY_CONFIGURATION,
|
||||
updated_policy_version,
|
||||
res.getErr()
|
||||
).notify();
|
||||
return genError(error_str);
|
||||
}
|
||||
i_service_controller->moveChangedPolicies();
|
||||
@ -648,6 +590,11 @@ private:
|
||||
"Send policy update report"
|
||||
);
|
||||
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::SUCCESS,
|
||||
UpdatesConfigType::POLICY
|
||||
).notify();
|
||||
|
||||
dbgInfo(D_ORCHESTRATOR) << "Policy update report was successfully sent to fog";
|
||||
|
||||
return Maybe<void>();
|
||||
@ -683,10 +630,24 @@ private:
|
||||
);
|
||||
|
||||
if (!new_data_files.ok()) {
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::DATA,
|
||||
UpdatesFailureReason::DOWNLOAD_FILE,
|
||||
resource_file.getFileName(),
|
||||
new_data_files.getErr()
|
||||
).notify();
|
||||
return genError("Failed to download new data file, Error: " + new_data_files.getErr());
|
||||
}
|
||||
auto new_data_file_input = i_orchestration_tools->readFile(new_data_files.unpack());
|
||||
if (!new_data_file_input.ok()) {
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::DATA,
|
||||
UpdatesFailureReason::HANDLE_FILE,
|
||||
resource_file.getFileName(),
|
||||
"Failed to read new data file, Error: " + new_data_file_input.getErr()
|
||||
).notify();
|
||||
return genError("Failed to read new data file, Error: " + new_data_file_input.getErr());
|
||||
}
|
||||
|
||||
@ -702,21 +663,35 @@ private:
|
||||
<< e.what()
|
||||
<< ". Content: "
|
||||
<< new_data_files.unpack();
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::DATA,
|
||||
UpdatesFailureReason::HANDLE_FILE,
|
||||
new_data_files.unpack(),
|
||||
string("Failed to load data from JSON file, Error: ") + e.what()
|
||||
).notify();
|
||||
return genError(e.what());
|
||||
}
|
||||
|
||||
for (const auto &data_file : parsed_data) {
|
||||
const string data_file_save_path = getPolicyConfigPath(data_file.first, Config::ConfigFileType::Data);
|
||||
Maybe<string> new_data_file =
|
||||
Singleton::Consume<I_Downloader>::by<OrchestrationComp>()->downloadFileFromURL(
|
||||
data_file.second.getDownloadPath(),
|
||||
data_file.second.getChecksum(),
|
||||
I_OrchestrationTools::SELECTED_CHECKSUM_TYPE,
|
||||
"data_" + data_file.first
|
||||
);
|
||||
Singleton::Consume<I_Downloader>::by<OrchestrationComp>()->downloadFileFromURL(
|
||||
data_file.second.getDownloadPath(),
|
||||
data_file.second.getChecksum(),
|
||||
I_OrchestrationTools::SELECTED_CHECKSUM_TYPE,
|
||||
"data_" + data_file.first
|
||||
);
|
||||
|
||||
if (!new_data_file.ok()) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to download the " << data_file.first << " data file.";
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::DATA,
|
||||
UpdatesFailureReason::DOWNLOAD_FILE,
|
||||
data_file.first,
|
||||
new_data_file.getErr()
|
||||
).notify();
|
||||
return new_data_file.passErr();
|
||||
}
|
||||
auto data_new_checksum = getChecksum(new_data_file.unpack());
|
||||
@ -729,6 +704,16 @@ private:
|
||||
<< data_new_checksum;
|
||||
|
||||
dbgWarning(D_ORCHESTRATOR) << current_error.str();
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::DATA,
|
||||
UpdatesFailureReason::CHECKSUM_UNMATCHED,
|
||||
data_file.first,
|
||||
" Expected checksum: " +
|
||||
data_file.second.getChecksum() +
|
||||
". Downloaded checksum: " +
|
||||
data_new_checksum
|
||||
).notify();
|
||||
return genError(current_error.str());
|
||||
}
|
||||
if (!i_orchestration_tools->copyFile(new_data_file.unpack(), data_file_save_path)) {
|
||||
@ -741,6 +726,10 @@ private:
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to copy a new agents' data file to " << data_file_path;
|
||||
}
|
||||
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::SUCCESS,
|
||||
UpdatesConfigType::DATA
|
||||
).notify();
|
||||
return Maybe<void>();
|
||||
}
|
||||
|
||||
@ -751,8 +740,7 @@ private:
|
||||
|
||||
dbgInfo(D_ORCHESTRATOR) << "There is a new settings file.";
|
||||
GetResourceFile resource_file(GetResourceFile::ResourceFileType::SETTINGS);
|
||||
Maybe<string> new_settings_file =
|
||||
Singleton::Consume<I_Downloader>::by<OrchestrationComp>()->downloadFile(
|
||||
Maybe<string> new_settings_file = Singleton::Consume<I_Downloader>::by<OrchestrationComp>()->downloadFile(
|
||||
orch_settings.unpack(),
|
||||
I_OrchestrationTools::SELECTED_CHECKSUM_TYPE,
|
||||
resource_file
|
||||
@ -762,6 +750,13 @@ private:
|
||||
dbgWarning(D_ORCHESTRATOR)
|
||||
<< "Failed to download the new settings file. Error: "
|
||||
<< new_settings_file.getErr();
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::SETTINGS,
|
||||
UpdatesFailureReason::DOWNLOAD_FILE,
|
||||
resource_file.getFileName(),
|
||||
new_settings_file.getErr()
|
||||
).notify();
|
||||
return genError("Failed to download the new settings file. Error: " + new_settings_file.getErr());
|
||||
}
|
||||
|
||||
@ -769,6 +764,10 @@ private:
|
||||
if (res.ok()) {
|
||||
settings_file_path = *res;
|
||||
reloadConfiguration();
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::SUCCESS,
|
||||
UpdatesConfigType::SETTINGS
|
||||
).notify();
|
||||
return Maybe<void>();
|
||||
}
|
||||
|
||||
@ -877,11 +876,13 @@ private:
|
||||
|
||||
if (!response.ok()) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to get the update. Error: " << response.getErr();
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::LAST_UPDATE,
|
||||
OrchestrationStatusResult::FAILED,
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::GENERAL,
|
||||
UpdatesFailureReason::GET_UPDATE_REQUEST,
|
||||
"",
|
||||
"Warning: Agent/Gateway failed during the update process. Contact Check Point support."
|
||||
);
|
||||
).notify();
|
||||
|
||||
return genError(response.getErr());
|
||||
}
|
||||
@ -924,10 +925,10 @@ private:
|
||||
OrchSettings orch_settings = response.getSettings();
|
||||
OrchData orch_data = response.getData();
|
||||
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::LAST_UPDATE,
|
||||
OrchestrationStatusResult::SUCCESS
|
||||
);
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::SUCCESS,
|
||||
UpdatesConfigType::GENERAL
|
||||
).notify();
|
||||
i_orchestration_status->setIsConfigurationUpdated(
|
||||
EnumArray<OrchestrationStatusConfigType, bool>(
|
||||
orch_manifest.ok(), orch_policy.ok(), orch_settings.ok(), orch_data.ok()
|
||||
@ -1017,6 +1018,10 @@ private:
|
||||
}
|
||||
|
||||
if (maybe_errors != "") return genError(maybe_errors);
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::SUCCESS,
|
||||
UpdatesConfigType::GENERAL
|
||||
).notify();
|
||||
return Maybe<void>();
|
||||
}
|
||||
|
||||
@ -1196,6 +1201,13 @@ private:
|
||||
dbgTrace(D_ORCHESTRATOR) << "The settings directory is " << settings_file_path;
|
||||
if (!i_orchestration_tools->copyFile(new_settings_file, settings_file_path)) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to update the settings.";
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::SETTINGS,
|
||||
UpdatesFailureReason::HANDLE_FILE,
|
||||
settings_file_path,
|
||||
"Failed to update the settings"
|
||||
).notify();
|
||||
return genError("Failed to update the settings");
|
||||
}
|
||||
|
||||
@ -1443,20 +1455,24 @@ private:
|
||||
<< check_update_result.getErr()
|
||||
<< ", new check will be every: "
|
||||
<< sleep_interval << " seconds";
|
||||
|
||||
health_check_status_listener.setStatus(
|
||||
HealthCheckStatus::UNHEALTHY,
|
||||
OrchestrationStatusFieldType::LAST_UPDATE,
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::GENERAL,
|
||||
UpdatesFailureReason::CHECK_UPDATE,
|
||||
"",
|
||||
"Failed during check update. Error: " + check_update_result.getErr()
|
||||
);
|
||||
).notify();
|
||||
return;
|
||||
}
|
||||
failure_count = 0;
|
||||
dbgDebug(D_ORCHESTRATOR) << "Check update process completed successfully";
|
||||
health_check_status_listener.setStatus(
|
||||
HealthCheckStatus::HEALTHY,
|
||||
OrchestrationStatusFieldType::LAST_UPDATE
|
||||
);
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::SUCCESS,
|
||||
UpdatesConfigType::GENERAL,
|
||||
UpdatesFailureReason::CHECK_UPDATE,
|
||||
"",
|
||||
"Check update procces succeeded!"
|
||||
).notify();
|
||||
sleep_interval = policy.getSleepInterval();
|
||||
if (!is_new_success) {
|
||||
dbgInfo(D_ORCHESTRATOR)
|
||||
@ -1491,11 +1507,13 @@ private:
|
||||
sleep_interval = policy.getErrorSleepInterval();
|
||||
Maybe<void> registration_status(genError("Not running yet."));
|
||||
while (!(registration_status = registerToTheFog()).ok()) {
|
||||
health_check_status_listener.setStatus(
|
||||
HealthCheckStatus::UNHEALTHY,
|
||||
OrchestrationStatusFieldType::REGISTRATION,
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::GENERAL,
|
||||
UpdatesFailureReason::REGISTRATION,
|
||||
"",
|
||||
registration_status.getErr()
|
||||
);
|
||||
).notify();
|
||||
sleep_interval = getConfigurationWithDefault<int>(
|
||||
30,
|
||||
"orchestration",
|
||||
@ -1515,10 +1533,11 @@ private:
|
||||
|
||||
Singleton::Consume<I_MainLoop>::by<OrchestrationComp>()->yield(chrono::seconds(1));
|
||||
|
||||
health_check_status_listener.setStatus(
|
||||
HealthCheckStatus::HEALTHY,
|
||||
OrchestrationStatusFieldType::REGISTRATION
|
||||
);
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::SUCCESS,
|
||||
UpdatesConfigType::GENERAL,
|
||||
UpdatesFailureReason::REGISTRATION
|
||||
).notify();
|
||||
|
||||
LogGen(
|
||||
"Check Point Orchestration nano service successfully started",
|
||||
@ -1552,16 +1571,18 @@ private:
|
||||
if (!Singleton::Consume<I_ManifestController>::by<OrchestrationComp>()->loadAfterSelfUpdate()) {
|
||||
// Should restore from backup
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to load Orchestration after self-update";
|
||||
health_check_status_listener.setStatus(
|
||||
HealthCheckStatus::UNHEALTHY,
|
||||
OrchestrationStatusFieldType::LAST_UPDATE,
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::GENERAL,
|
||||
UpdatesFailureReason::ORCHESTRATION_SELF_UPDATE,
|
||||
"",
|
||||
"Failed to load Orchestration after self-update"
|
||||
);
|
||||
).notify();
|
||||
} else {
|
||||
health_check_status_listener.setStatus(
|
||||
HealthCheckStatus::HEALTHY,
|
||||
OrchestrationStatusFieldType::MANIFEST
|
||||
);
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::SUCCESS,
|
||||
UpdatesConfigType::MANIFEST
|
||||
).notify();
|
||||
}
|
||||
|
||||
setUpgradeTime();
|
||||
@ -1911,7 +1932,7 @@ private:
|
||||
ReportIS::Audience::INTERNAL
|
||||
);
|
||||
hybrid_mode_metric.registerListener();
|
||||
health_check_status_listener.registerListener();
|
||||
updates_process_reporter_listener.registerListener();
|
||||
}
|
||||
|
||||
void
|
||||
@ -2024,7 +2045,7 @@ private:
|
||||
unsigned int sleep_interval = 0;
|
||||
bool is_new_success = false;
|
||||
OrchestrationPolicy policy;
|
||||
HealthCheckStatusListener health_check_status_listener;
|
||||
UpdatesProcessReporter updates_process_reporter_listener;
|
||||
HybridModeMetric hybrid_mode_metric;
|
||||
EnvDetails env_details;
|
||||
chrono::minutes upgrade_delay_time;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "cereal/types/set.hpp"
|
||||
#include "agent_core_utilities.h"
|
||||
#include "namespace_data.h"
|
||||
#include "updates_process_event.h"
|
||||
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
@ -469,6 +470,13 @@ OrchestrationTools::Impl::packagesToJsonFile(const map<packageName, Package> &pa
|
||||
archive_out(cereal::make_nvp("packages", packges_vector));
|
||||
} catch (cereal::Exception &e) {
|
||||
dbgDebug(D_ORCHESTRATOR) << "Failed to write vector of packages to JSON file " << path << ", " << e.what();
|
||||
UpdatesProcessEvent(
|
||||
UpdatesProcessResult::FAILED,
|
||||
UpdatesConfigType::MANIFEST,
|
||||
UpdatesFailureReason::HANDLE_FILE,
|
||||
path,
|
||||
string("Failed to write vector of packages to JSON file. Error: ") + e.what()
|
||||
).notify();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "agent_details.h"
|
||||
#include "customized_cereal_map.h"
|
||||
#include "health_check_status/health_check_status.h"
|
||||
#include "updates_process_event.h"
|
||||
#include "declarative_policy_utils.h"
|
||||
|
||||
using namespace testing;
|
||||
@ -358,6 +359,7 @@ private:
|
||||
TEST_F(OrchestrationTest, hybridModeRegisterLocalAgentRoutine)
|
||||
{
|
||||
EXPECT_CALL(rest, mockRestCall(_, _, _)).WillRepeatedly(Return(true));
|
||||
|
||||
Singleton::Consume<Config::I_Config>::from(config_comp)->loadConfiguration(
|
||||
vector<string>{"--orchestration-mode=hybrid_mode"}
|
||||
);
|
||||
@ -376,7 +378,6 @@ TEST_F(OrchestrationTest, hybridModeRegisterLocalAgentRoutine)
|
||||
expectDetailsResolver();
|
||||
EXPECT_CALL(mock_update_communication, getUpdate(_));
|
||||
EXPECT_CALL(mock_status, setLastUpdateAttempt());
|
||||
EXPECT_CALL(mock_status, setFieldStatus(_, _, _));
|
||||
EXPECT_CALL(mock_status, setIsConfigurationUpdated(_));
|
||||
|
||||
EXPECT_CALL(mock_ml, yield(A<chrono::microseconds>()))
|
||||
@ -584,7 +585,6 @@ TEST_F(OrchestrationTest, check_sending_registration_data)
|
||||
expectDetailsResolver();
|
||||
EXPECT_CALL(mock_update_communication, getUpdate(_));
|
||||
EXPECT_CALL(mock_status, setLastUpdateAttempt());
|
||||
EXPECT_CALL(mock_status, setFieldStatus(_, _, _));
|
||||
EXPECT_CALL(mock_status, setIsConfigurationUpdated(_));
|
||||
|
||||
EXPECT_CALL(mock_ml, yield(A<chrono::microseconds>()))
|
||||
@ -761,10 +761,6 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdatRollback)
|
||||
).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion("/test"));
|
||||
EXPECT_CALL(mock_status, setLastUpdateAttempt());
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::LAST_UPDATE, OrchestrationStatusResult::SUCCESS, "")
|
||||
);
|
||||
EXPECT_CALL(mock_status, setIsConfigurationUpdated(A<EnumArray<OrchestrationStatusConfigType, bool>>())
|
||||
).WillOnce(
|
||||
Invoke(
|
||||
@ -940,10 +936,6 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdate)
|
||||
).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion("/test"));
|
||||
EXPECT_CALL(mock_status, setLastUpdateAttempt());
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::LAST_UPDATE, OrchestrationStatusResult::SUCCESS, "")
|
||||
);
|
||||
EXPECT_CALL(mock_status, setIsConfigurationUpdated(A<EnumArray<OrchestrationStatusConfigType, bool>>())
|
||||
).WillOnce(
|
||||
Invoke(
|
||||
@ -1108,14 +1100,6 @@ TEST_F(OrchestrationTest, manifestUpdate)
|
||||
);
|
||||
|
||||
EXPECT_CALL(mock_status, setLastUpdateAttempt());
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::LAST_UPDATE, OrchestrationStatusResult::SUCCESS, "")
|
||||
);
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::MANIFEST, OrchestrationStatusResult::SUCCESS, "")
|
||||
);
|
||||
EXPECT_CALL(mock_status, setIsConfigurationUpdated(A<EnumArray<OrchestrationStatusConfigType, bool>>())
|
||||
).WillOnce(
|
||||
Invoke(
|
||||
@ -1237,10 +1221,6 @@ TEST_F(OrchestrationTest, getBadPolicyUpdate)
|
||||
.WillOnce(ReturnRef(second_val)
|
||||
);
|
||||
EXPECT_CALL(mock_status, setLastUpdateAttempt());
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::LAST_UPDATE, OrchestrationStatusResult::SUCCESS, "")
|
||||
);
|
||||
EXPECT_CALL(mock_status, setIsConfigurationUpdated(A<EnumArray<OrchestrationStatusConfigType, bool>>())
|
||||
).WillOnce(
|
||||
Invoke(
|
||||
@ -1271,7 +1251,7 @@ TEST_F(OrchestrationTest, getBadPolicyUpdate)
|
||||
EXPECT_CALL(
|
||||
mock_service_controller,
|
||||
updateServiceConfiguration(string("policy path"), "", expected_data_types, "", "", _)
|
||||
).WillOnce(Return(Maybe<void>(genError(string("")))));
|
||||
).WillOnce(Return(Maybe<void>(genError(string("Fail to load policy")))));
|
||||
|
||||
EXPECT_CALL(mock_ml, yield(A<chrono::microseconds>()))
|
||||
.WillOnce(
|
||||
@ -1328,6 +1308,7 @@ TEST_F(OrchestrationTest, failedDownloadSettings)
|
||||
|
||||
EXPECT_CALL(mock_update_communication, authenticateAgent()).WillOnce(Return(Maybe<void>()));
|
||||
expectDetailsResolver();
|
||||
|
||||
EXPECT_CALL(mock_manifest_controller, loadAfterSelfUpdate()).WillOnce(Return(false));
|
||||
EXPECT_CALL(mock_orchestration_tools, calculateChecksum(Package::ChecksumTypes::SHA256, manifest_file_path))
|
||||
.WillOnce(Return(manifest_checksum));
|
||||
@ -1359,22 +1340,10 @@ TEST_F(OrchestrationTest, failedDownloadSettings)
|
||||
);
|
||||
|
||||
EXPECT_CALL(mock_status, setLastUpdateAttempt());
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::LAST_UPDATE, OrchestrationStatusResult::SUCCESS, "")
|
||||
).Times(1);
|
||||
|
||||
string manifest_err =
|
||||
"Critical Error: Agent/Gateway was not fully deployed on host 'hostname' "
|
||||
"and is not enforcing a security policy. Retry installation or contact Check Point support.";
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(
|
||||
OrchestrationStatusFieldType::MANIFEST,
|
||||
OrchestrationStatusResult::FAILED,
|
||||
manifest_err
|
||||
)
|
||||
).Times(1);
|
||||
EXPECT_CALL(mock_status, getManifestError()).WillOnce(ReturnRef(manifest_err));
|
||||
|
||||
EXPECT_CALL(mock_status, setIsConfigurationUpdated(A<EnumArray<OrchestrationStatusConfigType, bool>>())
|
||||
@ -1475,10 +1444,6 @@ TEST_P(OrchestrationTest, orchestrationFirstRun)
|
||||
.WillOnce(Return(data_checksum));
|
||||
|
||||
EXPECT_CALL(mock_status, setLastUpdateAttempt());
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::LAST_UPDATE, OrchestrationStatusResult::SUCCESS, "")
|
||||
);
|
||||
EXPECT_CALL(mock_status, setIsConfigurationUpdated(A<EnumArray<OrchestrationStatusConfigType, bool>>())
|
||||
).WillOnce(
|
||||
Invoke(
|
||||
@ -1537,23 +1502,6 @@ TEST_P(OrchestrationTest, orchestrationFirstRun)
|
||||
} catch (const invalid_argument& e) {}
|
||||
EXPECT_CALL(mock_status, writeStatusToFile());
|
||||
|
||||
vector<HealthCheckStatusReply> reply;
|
||||
bool is_named_query = GetParam();
|
||||
if (is_named_query) {
|
||||
auto all_comps_status_reply = HealthCheckStatusEvent().performNamedQuery();
|
||||
for (auto &elem : all_comps_status_reply) {
|
||||
reply.push_back(elem.second);
|
||||
}
|
||||
} else {
|
||||
reply = HealthCheckStatusEvent().query();
|
||||
}
|
||||
|
||||
ASSERT_EQ(reply.size(), 1);
|
||||
EXPECT_EQ(reply[0].getCompName(), "Orchestration");
|
||||
EXPECT_EQ(reply[0].getStatus(), HealthCheckStatus::HEALTHY);
|
||||
|
||||
HealthCheckStatusEvent().notify();
|
||||
|
||||
orchestration_comp.fini();
|
||||
}
|
||||
|
||||
@ -1721,10 +1669,6 @@ TEST_F(OrchestrationTest, dataUpdate)
|
||||
);
|
||||
|
||||
EXPECT_CALL(mock_status, setLastUpdateAttempt());
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::LAST_UPDATE, OrchestrationStatusResult::SUCCESS, "")
|
||||
);
|
||||
EXPECT_CALL(mock_status, setIsConfigurationUpdated(A<EnumArray<OrchestrationStatusConfigType, bool>>())
|
||||
).WillOnce(
|
||||
Invoke(
|
||||
|
@ -32,6 +32,7 @@
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_ORCHESTRATOR);
|
||||
|
||||
class UpdateCommunication::Impl
|
||||
:
|
||||
public ServerRest,
|
||||
|
@ -0,0 +1 @@
|
||||
add_library(updates_process_reporter updates_process_event.cc updates_process_reporter.cc)
|
@ -0,0 +1,124 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "updates_process_event.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_UPDATES_PROCESS_REPORTER);
|
||||
|
||||
UpdatesProcessEvent::UpdatesProcessEvent(
|
||||
UpdatesProcessResult _result,
|
||||
UpdatesConfigType _type,
|
||||
UpdatesFailureReason _reason,
|
||||
const std::string &_detail,
|
||||
const std::string &_description)
|
||||
:
|
||||
result(_result),
|
||||
type(_type),
|
||||
reason(_reason),
|
||||
detail(_detail),
|
||||
description(_description)
|
||||
{
|
||||
string report =
|
||||
"Result: " + convertUpdateProcessResultToStr(result) +
|
||||
", Reason: " + convertUpdatesFailureReasonToStr(reason) +
|
||||
", Type: " + convertUpdatesConfigTypeToStr(type) +
|
||||
", Detail: " + detail +
|
||||
", Description: " + description;
|
||||
dbgTrace(D_UPDATES_PROCESS_REPORTER) << "Updates process event: " << report;
|
||||
}
|
||||
|
||||
OrchestrationStatusFieldType
|
||||
UpdatesProcessEvent::getStatusFieldType() const
|
||||
{
|
||||
if (reason == UpdatesFailureReason::REGISTRATION) {
|
||||
return OrchestrationStatusFieldType::REGISTRATION;
|
||||
}
|
||||
if (type == UpdatesConfigType::MANIFEST) {
|
||||
return OrchestrationStatusFieldType::MANIFEST;
|
||||
}
|
||||
return OrchestrationStatusFieldType::LAST_UPDATE;
|
||||
}
|
||||
|
||||
OrchestrationStatusResult
|
||||
UpdatesProcessEvent::getOrchestrationStatusResult() const
|
||||
{
|
||||
return result == UpdatesProcessResult::SUCCESS ?
|
||||
OrchestrationStatusResult::SUCCESS :
|
||||
OrchestrationStatusResult::FAILED;
|
||||
}
|
||||
|
||||
string
|
||||
UpdatesProcessEvent::parseDescription() const
|
||||
{
|
||||
stringstream err;
|
||||
if (description.empty() || result == UpdatesProcessResult::SUCCESS) return "";
|
||||
|
||||
switch (reason) {
|
||||
case UpdatesFailureReason::CHECK_UPDATE: {
|
||||
err << description;
|
||||
break;
|
||||
}
|
||||
case UpdatesFailureReason::REGISTRATION: {
|
||||
err << "Registration failed. Error: " << description;
|
||||
break;
|
||||
}
|
||||
case UpdatesFailureReason::GET_UPDATE_REQUEST: {
|
||||
err << "Failed to get update request. Error: " << description;
|
||||
break;
|
||||
}
|
||||
case UpdatesFailureReason::DOWNLOAD_FILE : {
|
||||
err << "Failed to download the file " << detail << ". Error: " << description;
|
||||
break;
|
||||
}
|
||||
case UpdatesFailureReason::HANDLE_FILE : {
|
||||
err << "Failed to handle the file " << detail << ". " << description;
|
||||
break;
|
||||
}
|
||||
case UpdatesFailureReason::INSTALLATION_QUEUE : {
|
||||
err << "Installation queue creation failed. Error: " << description;
|
||||
break;
|
||||
}
|
||||
case UpdatesFailureReason::INSTALL_PACKAGE : {
|
||||
err << "Failed to install the package " << detail << ". Error: " << description;
|
||||
break;
|
||||
}
|
||||
case UpdatesFailureReason::CHECKSUM_UNMATCHED : {
|
||||
err << "Checksums do not match for the file: " << detail << ". " << description;
|
||||
break;
|
||||
}
|
||||
case UpdatesFailureReason::POLICY_CONFIGURATION : {
|
||||
err << "Failed to configure policy version: " << detail << ". Error: " << description;
|
||||
break;
|
||||
}
|
||||
case UpdatesFailureReason::POLICY_FOG_CONFIGURATION : {
|
||||
err << "Failed to configure the fog address: " << detail << ". Error: " << description;
|
||||
break;
|
||||
}
|
||||
case UpdatesFailureReason::ORCHESTRATION_SELF_UPDATE : {
|
||||
err << description;
|
||||
break;
|
||||
}
|
||||
case UpdatesFailureReason::NONE : {
|
||||
err << description;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return err.str();
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "updates_process_reporter.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "debug.h"
|
||||
#include "log_generator.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_UPDATES_PROCESS_REPORTER);
|
||||
|
||||
vector<UpdatesProcessReport> UpdatesProcessReporter::reports;
|
||||
|
||||
void
|
||||
UpdatesProcessReporter::upon(const UpdatesProcessEvent &event)
|
||||
{
|
||||
if (event.getReason() == UpdatesFailureReason::CHECK_UPDATE) {
|
||||
if (event.getResult() == UpdatesProcessResult::SUCCESS && reports.empty()) {
|
||||
dbgTrace(D_UPDATES_PROCESS_REPORTER) << "Update proccess finished successfully";
|
||||
return;
|
||||
}
|
||||
dbgTrace(D_UPDATES_PROCESS_REPORTER) << "Update proccess finished with errors";
|
||||
reports.emplace_back(
|
||||
UpdatesProcessReport(
|
||||
event.getResult(),
|
||||
event.getType(),
|
||||
event.getReason(),
|
||||
event.parseDescription()
|
||||
)
|
||||
);
|
||||
sendReoprt();
|
||||
return;
|
||||
}
|
||||
if (event.getResult() == UpdatesProcessResult::SUCCESS || event.getResult() == UpdatesProcessResult::UNSET) return;
|
||||
reports.emplace_back(
|
||||
UpdatesProcessReport(event.getResult(), event.getType(), event.getReason(), event.parseDescription())
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
UpdatesProcessReporter::sendReoprt()
|
||||
{
|
||||
stringstream all_reports;
|
||||
all_reports << "Updates process reports:" << endl;
|
||||
for (const auto &report : reports) {
|
||||
all_reports << report.toString() << endl;
|
||||
}
|
||||
reports.clear();
|
||||
dbgTrace(D_UPDATES_PROCESS_REPORTER) << "Sending updates process report: " << endl << all_reports.str();
|
||||
LogGen(
|
||||
"Updates process report",
|
||||
ReportIS::Audience::INTERNAL,
|
||||
ReportIS::Severity::HIGH,
|
||||
ReportIS::Priority::HIGH,
|
||||
ReportIS::Tags::ORCHESTRATOR
|
||||
) << LogField("eventMessage", all_reports.str());
|
||||
}
|
@ -273,55 +273,58 @@ DeepParser::onKv(const char *k, size_t k_len, const char *v, size_t v_len, int f
|
||||
// Detect and decode potential base64 chunks in the value before further processing
|
||||
|
||||
bool base64ParamFound = false;
|
||||
dbgTrace(D_WAAP_DEEP_PARSER) << " ===Processing potential base64===";
|
||||
std::string decoded_val, decoded_key;
|
||||
Waap::Util::BinaryFileType base64BinaryFileType = Waap::Util::BinaryFileType::FILE_TYPE_NONE;
|
||||
base64_variants base64_status = Waap::Util::b64Test(cur_val, decoded_key, decoded_val, base64BinaryFileType);
|
||||
if (m_depth == 1 && flags == BUFFERED_RECEIVER_F_MIDDLE && m_key.depth() == 1 && m_key.first() != "#base64"){
|
||||
dbgTrace(D_WAAP_DEEP_PARSER) << " === will not check base64 since prev data block was not b64-encoded ===";
|
||||
} else {
|
||||
dbgTrace(D_WAAP_DEEP_PARSER) << " ===Processing potential base64===";
|
||||
std::string decoded_val, decoded_key;
|
||||
base64_variants base64_status = Waap::Util::b64Test(cur_val, decoded_key, decoded_val, base64BinaryFileType);
|
||||
|
||||
dbgTrace(D_WAAP_DEEP_PARSER)
|
||||
<< " status = "
|
||||
<< base64_status
|
||||
<< " key = "
|
||||
<< decoded_key
|
||||
<< " value = "
|
||||
<< decoded_val;
|
||||
dbgTrace(D_WAAP_DEEP_PARSER)
|
||||
<< " status = "
|
||||
<< base64_status
|
||||
<< " key = "
|
||||
<< decoded_key
|
||||
<< " value = "
|
||||
<< decoded_val;
|
||||
|
||||
switch (base64_status) {
|
||||
case SINGLE_B64_CHUNK_CONVERT:
|
||||
cur_val = decoded_val;
|
||||
base64ParamFound = true;
|
||||
break;
|
||||
case KEY_VALUE_B64_PAIR:
|
||||
// going deep with new pair in case value is not empty
|
||||
if (decoded_val.size() > 0) {
|
||||
switch (base64_status) {
|
||||
case SINGLE_B64_CHUNK_CONVERT:
|
||||
cur_val = decoded_val;
|
||||
base64ParamFound = true;
|
||||
rc = onKv(
|
||||
decoded_key.c_str(),
|
||||
decoded_key.size(),
|
||||
cur_val.data(),
|
||||
cur_val.size(),
|
||||
flags,
|
||||
parser_depth
|
||||
break;
|
||||
case KEY_VALUE_B64_PAIR:
|
||||
// going deep with new pair in case value is not empty
|
||||
if (decoded_val.size() > 0) {
|
||||
cur_val = decoded_val;
|
||||
base64ParamFound = true;
|
||||
rc = onKv(
|
||||
decoded_key.c_str(),
|
||||
decoded_key.size(),
|
||||
cur_val.data(),
|
||||
cur_val.size(),
|
||||
flags,
|
||||
parser_depth
|
||||
);
|
||||
|
||||
dbgTrace(D_WAAP_DEEP_PARSER) << " rc = " << rc;
|
||||
if (rc != CONTINUE_PARSING) {
|
||||
return rc;
|
||||
dbgTrace(D_WAAP_DEEP_PARSER) << " rc = " << rc;
|
||||
if (rc != CONTINUE_PARSING) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CONTINUE_AS_IS:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CONTINUE_AS_IS:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (base64ParamFound) {
|
||||
dbgTrace(D_WAAP_DEEP_PARSER) << "DeepParser::onKv(): pushing #base64 prefix to the key.";
|
||||
m_key.push("#base64", 7, false);
|
||||
if (base64ParamFound) {
|
||||
dbgTrace(D_WAAP_DEEP_PARSER) << "DeepParser::onKv(): pushing #base64 prefix to the key.";
|
||||
m_key.push("#base64", 7, false);
|
||||
}
|
||||
}
|
||||
|
||||
// cur_val is later passed through some filters (such as urldecode) before JSON, XML or HTML is detected/decoded
|
||||
std::string orig_val = cur_val;
|
||||
|
||||
@ -472,19 +475,19 @@ DeepParser::onKv(const char *k, size_t k_len, const char *v, size_t v_len, int f
|
||||
if (rc != CONTINUE_PARSING) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (Waap::Util::detectJSONasParameter(cur_val, decoded_key, decoded_val)) {
|
||||
std::string json_decoded_val, json_decoded_key;
|
||||
if (Waap::Util::detectJSONasParameter(cur_val, json_decoded_key, json_decoded_val)) {
|
||||
dbgTrace(D_WAAP_DEEP_PARSER)
|
||||
<< " detectJSONasParameter was true: key = "
|
||||
<< decoded_key
|
||||
<< json_decoded_key
|
||||
<< " value = "
|
||||
<< decoded_val;
|
||||
<< json_decoded_val;
|
||||
|
||||
rc = onKv(
|
||||
decoded_key.c_str(),
|
||||
decoded_key.size(),
|
||||
decoded_val.data(),
|
||||
decoded_val.size(),
|
||||
json_decoded_key.c_str(),
|
||||
json_decoded_key.size(),
|
||||
json_decoded_val.data(),
|
||||
json_decoded_val.size(),
|
||||
flags,
|
||||
parser_depth
|
||||
);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define BUFFERED_RECEIVER_F_LAST 0x02
|
||||
#define BUFFERED_RECEIVER_F_BOTH (BUFFERED_RECEIVER_F_FIRST | BUFFERED_RECEIVER_F_LAST)
|
||||
#define BUFFERED_RECEIVER_F_UNNAMED 0x04
|
||||
#define BUFFERED_RECEIVER_F_MIDDLE 0x00
|
||||
|
||||
#if (DISTRO_centos6)
|
||||
// pre c++11 compiler doesn' support the "final" keyword
|
||||
|
@ -727,7 +727,6 @@ void SerializeToLocalAndRemoteSyncBase::syncWorker()
|
||||
"sync notification for '" + m_assetId + "'",
|
||||
ReportIS::AudienceTeam::WAAP,
|
||||
syncNotification,
|
||||
false,
|
||||
MessageCategory::GENERIC,
|
||||
ReportIS::Tags::WAF,
|
||||
ReportIS::Notification::SYNC_LEARNING
|
||||
|
@ -39,12 +39,19 @@ public:
|
||||
m_op = to_lower_copy(m_op);
|
||||
m_isCidr = false;
|
||||
m_value = "";
|
||||
m_isValid = true;
|
||||
|
||||
if (m_op == "basic") {
|
||||
// If op == "BASIC" - read numeric value
|
||||
ar(cereal::make_nvp("tag", m_tag));
|
||||
m_tag = to_lower_copy(m_tag);
|
||||
|
||||
if (m_tag != "sourceip" && m_tag != "sourceidentifier" && m_tag != "url" && m_tag != "hostname" &&
|
||||
m_tag != "keyword" && m_tag != "paramname" && m_tag != "paramvalue" && m_tag != "paramlocation" &&
|
||||
m_tag != "responsebody" && m_tag != "headername" && m_tag != "headervalue" ) {
|
||||
m_isValid = false;
|
||||
dbgDebug(D_WAAP_OVERRIDE) << "Invalid override tag: " << m_tag;
|
||||
}
|
||||
// The name "value" here is misleading. The real meaning is "regex pattern string"
|
||||
ar(cereal::make_nvp("value", m_value));
|
||||
|
||||
@ -73,12 +80,14 @@ public:
|
||||
m_operand2 = std::make_shared<Match>();
|
||||
ar(cereal::make_nvp("operand2", *m_operand2));
|
||||
m_isOverrideResponse = m_operand1->m_isOverrideResponse || m_operand2->m_isOverrideResponse;
|
||||
m_isValid = m_operand1->m_isValid && m_operand2->m_isValid;
|
||||
}
|
||||
else if (m_op == "not") {
|
||||
// If op is "NOT" get one operand
|
||||
m_operand1 = std::make_shared<Match>();
|
||||
ar(cereal::make_nvp("operand1", *m_operand1));
|
||||
m_isOverrideResponse = m_operand1->m_isOverrideResponse;
|
||||
m_isValid = m_operand1->m_isValid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,6 +129,10 @@ public:
|
||||
return m_isOverrideResponse;
|
||||
}
|
||||
|
||||
bool isValidMatch() const{
|
||||
return m_isValid;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_op;
|
||||
std::shared_ptr<Match> m_operand1;
|
||||
@ -130,6 +143,7 @@ private:
|
||||
Waap::Util::CIDRData m_cidr;
|
||||
bool m_isCidr;
|
||||
bool m_isOverrideResponse;
|
||||
bool m_isValid;
|
||||
};
|
||||
|
||||
class Behavior
|
||||
@ -189,6 +203,9 @@ private:
|
||||
|
||||
class Rule {
|
||||
public:
|
||||
|
||||
Rule(): m_match(), m_isChangingRequestData(false), isValid(true){}
|
||||
|
||||
bool operator==(const Rule &other) const;
|
||||
|
||||
template <typename _A>
|
||||
@ -202,6 +219,11 @@ public:
|
||||
m_id.clear();
|
||||
}
|
||||
ar(cereal::make_nvp("parsedMatch", m_match));
|
||||
if (!m_match.isValidMatch()) {
|
||||
dbgDebug(D_WAAP_OVERRIDE) << "An override rule was not load";
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
ar(cereal::make_nvp("parsedBehavior", m_behaviors));
|
||||
|
||||
m_isChangingRequestData = false;
|
||||
@ -242,6 +264,7 @@ public:
|
||||
dbgTrace(D_WAAP_OVERRIDE) << "Rule not matched";
|
||||
}
|
||||
|
||||
|
||||
bool isChangingRequestData() const {
|
||||
return m_isChangingRequestData;
|
||||
}
|
||||
@ -253,11 +276,16 @@ public:
|
||||
return m_id;
|
||||
}
|
||||
|
||||
bool isValidRule() const {
|
||||
return isValid;
|
||||
}
|
||||
|
||||
private:
|
||||
Match m_match;
|
||||
bool m_isChangingRequestData;
|
||||
std::vector<Behavior> m_behaviors;
|
||||
std::string m_id;
|
||||
bool isValid;
|
||||
};
|
||||
|
||||
class Policy {
|
||||
@ -270,6 +298,10 @@ public:
|
||||
|
||||
for (std::vector<Waap::Override::Rule>::const_iterator it = rules.begin(); it != rules.end(); ++it) {
|
||||
const Waap::Override::Rule& rule = *it;
|
||||
if (!rule.isValidRule()) {
|
||||
dbgWarning(D_WAAP_OVERRIDE) << "rule is not valid";
|
||||
continue;
|
||||
}
|
||||
if (rule.isChangingRequestData())
|
||||
{
|
||||
m_RequestOverrides.push_back(rule);
|
||||
|
@ -175,7 +175,7 @@ copyFile(const string &src, const string &dest, bool overide_if_exists, mode_t p
|
||||
struct stat stat_buf;
|
||||
int source_fd = open(src.c_str(), O_RDONLY);
|
||||
fstat(source_fd, &stat_buf);
|
||||
int dest_fd = open(dest.c_str(), O_WRONLY | O_CREAT, permission);
|
||||
int dest_fd = open(dest.c_str(), O_WRONLY | O_CREAT | O_TRUNC, permission);
|
||||
int bytes_copied = 1;
|
||||
while (bytes_copied > 0) {
|
||||
static const int buf_size = 4096*1000;
|
||||
|
@ -37,8 +37,11 @@ TEST_F(AgentCoreUtilUT, filesTest)
|
||||
EXPECT_FALSE(NGEN::Filesystem::exists("/i/am/not/a/real/path"));
|
||||
|
||||
const vector<string> lines{"i am a line in the text file", "i am iron man"};
|
||||
const vector<string> lines_b{"i am a line 2 in the text file", "i am iron man 2", "hello again"};
|
||||
CPTestTempfile test_file(lines);
|
||||
CPTestTempfile test_file_b(lines_b);
|
||||
ASSERT_TRUE(NGEN::Filesystem::exists(test_file.fname));
|
||||
ASSERT_TRUE(NGEN::Filesystem::exists(test_file_b.fname));
|
||||
|
||||
string output_orig = test_file.readFile();
|
||||
string new_path = test_file.fname + ".new";
|
||||
@ -46,6 +49,7 @@ TEST_F(AgentCoreUtilUT, filesTest)
|
||||
ASSERT_TRUE(NGEN::Filesystem::exists(new_path));
|
||||
ASSERT_FALSE(NGEN::Filesystem::copyFile(test_file.fname, new_path, false));
|
||||
ASSERT_TRUE(NGEN::Filesystem::copyFile(test_file.fname, new_path, true));
|
||||
ASSERT_TRUE(NGEN::Filesystem::copyFile(test_file.fname, test_file_b.fname, true));
|
||||
string output_new;
|
||||
{
|
||||
ifstream new_file_stream(new_path);
|
||||
@ -55,11 +59,20 @@ TEST_F(AgentCoreUtilUT, filesTest)
|
||||
output_new = buffer.str();
|
||||
}
|
||||
|
||||
string output_test_b;
|
||||
ifstream new_file_stream(test_file_b.fname);
|
||||
ASSERT_TRUE(new_file_stream.good());
|
||||
stringstream buffer;
|
||||
buffer << new_file_stream.rdbuf();
|
||||
output_test_b = buffer.str();
|
||||
|
||||
EXPECT_EQ(output_orig, output_new);
|
||||
EXPECT_EQ(output_orig, output_test_b);
|
||||
EXPECT_THAT(output_new, HasSubstr("i am a line in the text file"));
|
||||
EXPECT_THAT(output_new, HasSubstr("i am iron man"));
|
||||
EXPECT_TRUE(NGEN::Filesystem::deleteFile(test_file.fname));
|
||||
EXPECT_TRUE(NGEN::Filesystem::deleteFile(new_path));
|
||||
EXPECT_TRUE(NGEN::Filesystem::deleteFile(test_file_b.fname));
|
||||
EXPECT_FALSE(NGEN::Filesystem::exists(test_file.fname));
|
||||
EXPECT_FALSE(NGEN::Filesystem::exists(new_path));
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "i_time_get.h"
|
||||
#include "i_encryptor.h"
|
||||
#include "i_shell_cmd.h"
|
||||
#include "i_rest_api.h"
|
||||
#include "i_instance_awareness.h"
|
||||
|
||||
#include "config.h"
|
||||
@ -41,6 +42,7 @@ class Messaging
|
||||
Singleton::Consume<I_TimeGet>,
|
||||
Singleton::Consume<I_ShellCmd>,
|
||||
Singleton::Consume<I_MainLoop>,
|
||||
Singleton::Consume<I_RestApi>,
|
||||
Singleton::Consume<I_InstanceAwareness>
|
||||
{
|
||||
public:
|
||||
|
@ -142,6 +142,7 @@ DEFINE_FLAG(D_COMPONENT, D_ALL)
|
||||
DEFINE_FLAG(D_LOCAL_POLICY, D_ORCHESTRATOR)
|
||||
DEFINE_FLAG(D_NGINX_POLICY, D_ORCHESTRATOR)
|
||||
DEFINE_FLAG(D_SERVICE_CONTROLLER, D_ORCHESTRATOR)
|
||||
DEFINE_FLAG(D_UPDATES_PROCESS_REPORTER, D_ORCHESTRATOR)
|
||||
|
||||
DEFINE_FLAG(D_GRADUAL_DEPLOYMENT, D_COMPONENT)
|
||||
DEFINE_FLAG(D_SDWAN, D_COMPONENT)
|
||||
|
@ -89,11 +89,4 @@ private:
|
||||
std::map<std::string, std::string> extended_status = {};
|
||||
};
|
||||
|
||||
class HealthCheckStatusEvent : public Event<HealthCheckStatusEvent, HealthCheckStatusReply>
|
||||
{
|
||||
public:
|
||||
HealthCheckStatusEvent() {}
|
||||
~HealthCheckStatusEvent() {}
|
||||
};
|
||||
|
||||
#endif // __HEALTH_CHECK_STATUS_H__
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "agent_core_utilities.h"
|
||||
#include "connection_comp.h"
|
||||
#include "rest.h"
|
||||
#include "debug.h"
|
||||
#include "messaging_buffer.h"
|
||||
|
||||
@ -25,6 +26,40 @@ using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_MESSAGING);
|
||||
|
||||
class FogConnectionChecker : public ServerRest
|
||||
{
|
||||
public:
|
||||
void
|
||||
doCall() override
|
||||
{
|
||||
dbgTrace(D_MESSAGING) << "Checking connection to the FOG";
|
||||
auto response = Singleton::Consume<I_Messaging>::from<Messaging>()->sendSyncMessage(
|
||||
HTTPMethod::GET,
|
||||
"/access-manager/health/live",
|
||||
string("")
|
||||
);
|
||||
if (!response.ok()) {
|
||||
dbgTrace(D_MESSAGING) << "Failed to check connection to the FOG";
|
||||
connected_to_fog = false;
|
||||
error = response.getErr().toString();
|
||||
return;
|
||||
}
|
||||
if (response.unpack().getHTTPStatusCode() == HTTPStatusCode::HTTP_OK) {
|
||||
dbgTrace(D_MESSAGING) << "Connected to the FOG";
|
||||
connected_to_fog = true;
|
||||
error = "";
|
||||
} else {
|
||||
dbgTrace(D_MESSAGING) << "No connection to the FOG";
|
||||
connected_to_fog = false;
|
||||
error = response.unpack().toString();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
S2C_PARAM(bool, connected_to_fog);
|
||||
S2C_PARAM(string, error);
|
||||
};
|
||||
|
||||
void
|
||||
MessagingComp::init()
|
||||
{
|
||||
@ -42,6 +77,13 @@ MessagingComp::init()
|
||||
"message",
|
||||
"Buffer Failed Requests"
|
||||
);
|
||||
|
||||
if (Singleton::exists<I_RestApi>()) {
|
||||
Singleton::Consume<I_RestApi>::by<Messaging>()->addRestCall<FogConnectionChecker>(
|
||||
RestAction::SHOW,
|
||||
"check-fog-connection"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "mocks/mock_messaging_connection.h"
|
||||
#include "rest.h"
|
||||
#include "rest_server.h"
|
||||
#include "mock/mock_messaging.h"
|
||||
#include "mock/mock_rest_api.h"
|
||||
#include "dummy_socket.h"
|
||||
|
||||
using namespace std;
|
||||
@ -26,12 +28,6 @@ operator<<(ostream &os, const Maybe<BufferedMessage> &)
|
||||
return os;
|
||||
}
|
||||
|
||||
static std::ostream &
|
||||
operator<<(std::ostream &os, const HTTPResponse &)
|
||||
{
|
||||
return os;
|
||||
}
|
||||
|
||||
static std::ostream &
|
||||
operator<<(std::ostream &os, const HTTPStatusCode &)
|
||||
{
|
||||
@ -51,6 +47,9 @@ public:
|
||||
{
|
||||
Debug::setUnitTestFlag(D_MESSAGING, Debug::DebugLevel::TRACE);
|
||||
EXPECT_CALL(mock_time_get, getMonotonicTime()).WillRepeatedly(Return(chrono::microseconds(0)));
|
||||
EXPECT_CALL(mock_rest, mockRestCall(RestAction::SHOW, "check-fog-connection", _))
|
||||
.WillOnce(WithArg<2>(Invoke(this, &TestMessagingComp::showFogConnection))
|
||||
);
|
||||
|
||||
ON_CALL(mock_agent_details, getFogDomain()).WillByDefault(Return(Maybe<string>(fog_addr)));
|
||||
ON_CALL(mock_agent_details, getFogPort()).WillByDefault(Return(Maybe<uint16_t>(fog_port)));
|
||||
@ -73,6 +72,13 @@ public:
|
||||
EXPECT_CALL(mock_proxy_conf, getProxyAuthentication(_)).WillRepeatedly(Return(string("cred")));
|
||||
}
|
||||
|
||||
bool
|
||||
showFogConnection(const unique_ptr<RestInit> &p)
|
||||
{
|
||||
show_fog_connection = p->getRest();
|
||||
return true;
|
||||
}
|
||||
|
||||
const string fog_addr = "127.0.0.1";
|
||||
int fog_port = 8080;
|
||||
CPTestTempfile agent_details_file;
|
||||
@ -85,16 +91,37 @@ public:
|
||||
NiceMock<MockTimeGet> mock_time_get;
|
||||
NiceMock<MockAgentDetails> mock_agent_details;
|
||||
NiceMock<MockProxyConfiguration> mock_proxy_conf;
|
||||
NiceMock<MockRestApi> mock_rest;
|
||||
NiceMock<MockMessaging> mock_message;
|
||||
unique_ptr<ServerRest> show_fog_connection;
|
||||
DummySocket dummy_socket;
|
||||
};
|
||||
|
||||
TEST_F(TestMessagingComp, testInitComp)
|
||||
TEST_F(TestMessagingComp, testCheckFogConnectivity)
|
||||
{
|
||||
EXPECT_CALL(
|
||||
mock_mainloop, addRecurringRoutine(I_MainLoop::RoutineType::Timer, _, _, "Delete expired cache entries", _)
|
||||
)
|
||||
.WillOnce(Return(0));
|
||||
messaging_comp.init();
|
||||
setAgentDetails();
|
||||
HTTPResponse res(
|
||||
HTTPStatusCode::HTTP_OK,
|
||||
string(
|
||||
"{"
|
||||
" \"up\": true,"
|
||||
" \"timestamp\":\"\""
|
||||
"}"
|
||||
)
|
||||
);
|
||||
|
||||
EXPECT_CALL(mock_message, sendSyncMessage(HTTPMethod::GET, "/access-manager/health/live", "", _, _))
|
||||
.WillOnce(Return(res));
|
||||
|
||||
stringstream ss("{}");
|
||||
Maybe<string> maybe_res = show_fog_connection->performRestCall(ss);
|
||||
EXPECT_TRUE(maybe_res.ok());
|
||||
EXPECT_EQ(maybe_res.unpack(),
|
||||
"{\n"
|
||||
" \"connected_to_fog\": true,\n"
|
||||
" \"error\": \"\"\n"
|
||||
"}"
|
||||
);
|
||||
}
|
||||
|
||||
TEST_F(TestMessagingComp, testSendSyncMessage)
|
||||
|
@ -28,6 +28,7 @@ target_link_libraries(
|
||||
orchestration_tools
|
||||
env_details
|
||||
local_policy_mgmt_gen
|
||||
updates_process_reporter
|
||||
curl
|
||||
|
||||
-Wl,--end-group
|
||||
|
@ -52,7 +52,7 @@ log-triggers:
|
||||
url-path: false
|
||||
url-query: false
|
||||
log-destination:
|
||||
cloud: true
|
||||
cloud: false
|
||||
stdout:
|
||||
format: json
|
||||
|
||||
|
@ -418,9 +418,9 @@ cp_print()
|
||||
printf "%b\n" "$1"
|
||||
fi
|
||||
if [ "$is_smb" != "1" ]; then
|
||||
printf "%b\n" "$1" >> ${LOG_FILE_PATH}/${LOG_PATH}/${INSTALLATION_LOG_FILE}
|
||||
printf "[%s] %b\n" "$(date +%Y-%m-%dT%H:%M:%S)" "$1" >> ${LOG_FILE_PATH}/${LOG_PATH}/${INSTALLATION_LOG_FILE}
|
||||
else
|
||||
printf "%b\n" "$1" >> ${SMB_LOG_FILE_PATH}/${LOG_PATH}/${INSTALLATION_LOG_FILE}
|
||||
printf "[%s] %b\n" "$(date +%Y-%m-%dT%H:%M:%S)" "$1" >> ${SMB_LOG_FILE_PATH}/${LOG_PATH}/${INSTALLATION_LOG_FILE}
|
||||
fi
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user