mirror of
https://github.com/openappsec/openappsec.git
synced 2025-09-29 19:24:26 +03:00
First release of open-appsec source code
This commit is contained in:
10
components/security_apps/orchestration/modules/CMakeLists.txt
Executable file
10
components/security_apps/orchestration/modules/CMakeLists.txt
Executable file
@@ -0,0 +1,10 @@
|
||||
add_library(
|
||||
orchestration_modules
|
||||
orchestration_policy.cc
|
||||
url_parser.cc
|
||||
package.cc
|
||||
orchestration_status.cc
|
||||
data.cc
|
||||
)
|
||||
|
||||
add_subdirectory(modules_ut)
|
52
components/security_apps/orchestration/modules/data.cc
Executable file
52
components/security_apps/orchestration/modules/data.cc
Executable file
@@ -0,0 +1,52 @@
|
||||
// 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 "orchestrator/data.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "sasal.h"
|
||||
|
||||
SASAL_START // Orchestration - Modules
|
||||
|
||||
using namespace std;
|
||||
using namespace cereal;
|
||||
|
||||
USE_DEBUG_FLAG(D_ORCHESTRATOR);
|
||||
|
||||
static const map<string, Data::ChecksumTypes> checksum_map = {
|
||||
{ "sha1sum", Data::ChecksumTypes::SHA1 },
|
||||
{ "sha256sum", Data::ChecksumTypes::SHA256 },
|
||||
{ "sha512sum", Data::ChecksumTypes::SHA512 },
|
||||
{ "md5sum", Data::ChecksumTypes::MD5 }
|
||||
};
|
||||
|
||||
void
|
||||
Data::serialize(JSONInputArchive &in_archive)
|
||||
{
|
||||
string checksum_type_as_string;
|
||||
in_archive(make_nvp("checksumType", checksum_type_as_string));
|
||||
if (checksum_map.find(checksum_type_as_string) != checksum_map.end()) {
|
||||
checksum_type = checksum_map.at(checksum_type_as_string);
|
||||
} else {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Unsupported checksum type: " << checksum_type_as_string;
|
||||
return;
|
||||
}
|
||||
in_archive(
|
||||
make_nvp("downloadPath", download_path),
|
||||
make_nvp("checksum", checksum_value),
|
||||
make_nvp("version", version)
|
||||
);
|
||||
}
|
||||
|
||||
SASAL_END
|
7
components/security_apps/orchestration/modules/modules_ut/CMakeLists.txt
Executable file
7
components/security_apps/orchestration/modules/modules_ut/CMakeLists.txt
Executable file
@@ -0,0 +1,7 @@
|
||||
link_directories(${BOOST_ROOT}/lib)
|
||||
|
||||
add_unit_test(
|
||||
orchestration_modules_ut
|
||||
"orchestration_policy_ut.cc;url_parser_ut.cc;package_ut.cc;orchestration_status_ut.cc;data_ut.cc;"
|
||||
"orchestration_modules;config;environment;metric;event_is;time_proxy;-lboost_regex"
|
||||
)
|
85
components/security_apps/orchestration/modules/modules_ut/data_ut.cc
Executable file
85
components/security_apps/orchestration/modules/modules_ut/data_ut.cc
Executable file
@@ -0,0 +1,85 @@
|
||||
#include "orchestrator/data.h"
|
||||
|
||||
#include "cereal/types/string.hpp"
|
||||
#include "cereal/archives/json.hpp"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
|
||||
#include "cptest.h"
|
||||
#include "customized_cereal_map.h"
|
||||
|
||||
using namespace testing;
|
||||
using namespace std;
|
||||
|
||||
class DataTest : public Test
|
||||
{
|
||||
public:
|
||||
bool
|
||||
load(stringstream &string_stream, Data &data)
|
||||
{
|
||||
try {
|
||||
cereal::JSONInputArchive archive_in(string_stream);
|
||||
data.serialize(archive_in);
|
||||
} catch (const cereal::Exception &) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(DataTest, doNothing)
|
||||
{
|
||||
}
|
||||
|
||||
TEST_F(DataTest, serializationFromString)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{"
|
||||
" \"version\": \"c\","
|
||||
" \"downloadPath\": \"https://a/data.json\",\n"
|
||||
" \"checksumType\": \"sha1sum\","
|
||||
" \"checksum\": \"8d4a5709673a05b380ba7d6567e28910019118f5\""
|
||||
"}";
|
||||
bool res = false;
|
||||
Data data;
|
||||
try {
|
||||
cereal::JSONInputArchive archive_in(string_stream);
|
||||
data.serialize(archive_in);
|
||||
res = true;
|
||||
} catch (const cereal::Exception &) {
|
||||
}
|
||||
EXPECT_EQ(true, res);
|
||||
|
||||
EXPECT_EQ(Data::ChecksumTypes::SHA1, data.getChecksumType());
|
||||
EXPECT_EQ("8d4a5709673a05b380ba7d6567e28910019118f5", data.getChecksum());
|
||||
EXPECT_EQ("c", data.getVersion());
|
||||
EXPECT_EQ("https://a/data.json", data.getDownloadPath());
|
||||
}
|
||||
|
||||
TEST_F(DataTest, serializationFromStringAsMap)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{\n"
|
||||
" \"ips\": {\n"
|
||||
" \"version\": \"c\","
|
||||
" \"downloadPath\": \"https://a/data.json\",\n"
|
||||
" \"checksumType\": \"sha1sum\","
|
||||
" \"checksum\": \"8d4a5709673a05b380ba7d6567e28910019118f5\""
|
||||
" }\n"
|
||||
"}\n";
|
||||
map<string, Data> data;
|
||||
bool res = false;
|
||||
try {
|
||||
cereal::JSONInputArchive archive_in(string_stream);
|
||||
cereal::load(archive_in, data);
|
||||
res = true;
|
||||
} catch (const cereal::Exception &e) {
|
||||
}
|
||||
EXPECT_EQ(true, res);
|
||||
|
||||
EXPECT_EQ(Data::ChecksumTypes::SHA1, data["ips"].getChecksumType());
|
||||
EXPECT_EQ("8d4a5709673a05b380ba7d6567e28910019118f5", data["ips"].getChecksum());
|
||||
EXPECT_EQ("c", data["ips"].getVersion());
|
||||
EXPECT_EQ("https://a/data.json", data["ips"].getDownloadPath());
|
||||
}
|
@@ -0,0 +1,158 @@
|
||||
#include "orchestration_policy.h"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include "cptest.h"
|
||||
#include "cereal/types/string.hpp"
|
||||
|
||||
using namespace testing;
|
||||
using namespace std;
|
||||
|
||||
class PolicyTest : public Test
|
||||
{
|
||||
public:
|
||||
PolicyTest() {}
|
||||
|
||||
void
|
||||
orchestrationPolicyToString(stringstream &string_stream)
|
||||
{
|
||||
cereal::JSONInputArchive archive_in(string_stream);
|
||||
orchestration_policy.serialize(archive_in);
|
||||
}
|
||||
|
||||
OrchestrationPolicy orchestration_policy;
|
||||
};
|
||||
|
||||
TEST_F(PolicyTest, doNothing)
|
||||
{
|
||||
}
|
||||
|
||||
TEST_F(PolicyTest, serialization)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{"
|
||||
" \"fog-address\": \"http://10.0.0.18:81/control/\","
|
||||
" \"agent-type\": \"13324sadsd2\","
|
||||
" \"pulling-interval\": 20,"
|
||||
" \"error-pulling-interval\": 15"
|
||||
"}";
|
||||
try {
|
||||
orchestrationPolicyToString(string_stream);
|
||||
} catch (cereal::Exception &e) {
|
||||
ASSERT_TRUE(false) << "Cereal threw an exception: " << e.what();
|
||||
}
|
||||
|
||||
EXPECT_EQ(15u, orchestration_policy.getErrorSleepInterval());
|
||||
EXPECT_EQ(20u, orchestration_policy.getSleepInterval());
|
||||
EXPECT_EQ("http://10.0.0.18:81/control/", orchestration_policy.getFogAddress());
|
||||
}
|
||||
|
||||
TEST_F(PolicyTest, noAgentType)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{"
|
||||
" \"fog-address\": \"http://10.0.0.18:81/control/\","
|
||||
" \"agent-type\": \"\","
|
||||
" \"pulling-interval\": 20,"
|
||||
" \"error-pulling-interval\": 15"
|
||||
"}";
|
||||
try {
|
||||
orchestrationPolicyToString(string_stream);
|
||||
} catch (cereal::Exception &e) {
|
||||
ASSERT_TRUE(false) << "Cereal threw an exception: " << e.what();
|
||||
}
|
||||
|
||||
EXPECT_EQ(15u, orchestration_policy.getErrorSleepInterval());
|
||||
EXPECT_EQ(20u, orchestration_policy.getSleepInterval());
|
||||
EXPECT_EQ("http://10.0.0.18:81/control/", orchestration_policy.getFogAddress());
|
||||
}
|
||||
|
||||
TEST_F(PolicyTest, zeroSleepIntervels)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{"
|
||||
" \"fog-address\": \"http://10.0.0.18:81/control/\","
|
||||
" \"agent-type\": \"13324sadsd2\","
|
||||
" \"pulling-interval\": 0,"
|
||||
" \"error-pulling-interval\": 0"
|
||||
"}";
|
||||
try {
|
||||
orchestrationPolicyToString(string_stream);
|
||||
} catch (cereal::Exception &e) {
|
||||
ASSERT_TRUE(false) << "Cereal threw an exception: " << e.what();
|
||||
}
|
||||
|
||||
EXPECT_EQ(0u, orchestration_policy.getErrorSleepInterval());
|
||||
EXPECT_EQ(0u, orchestration_policy.getSleepInterval());
|
||||
EXPECT_EQ("http://10.0.0.18:81/control/", orchestration_policy.getFogAddress());
|
||||
}
|
||||
|
||||
TEST_F(PolicyTest, operatorEqual)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{"
|
||||
" \"fog-address\": \"http://10.0.0.18:81/control/\","
|
||||
" \"pulling-interval\": 20,"
|
||||
" \"error-pulling-interval\": 15"
|
||||
"}";
|
||||
try {
|
||||
orchestrationPolicyToString(string_stream);
|
||||
} catch (cereal::Exception &e) {
|
||||
ASSERT_TRUE(false) << "Cereal threw an exception: " << e.what();
|
||||
}
|
||||
|
||||
OrchestrationPolicy orchestration_copy_policy;
|
||||
stringstream string_stream_copy;
|
||||
string_stream_copy << "{"
|
||||
" \"fog-address\": \"http://10.0.0.18:81/control/\","
|
||||
" \"pulling-interval\": 20,"
|
||||
" \"error-pulling-interval\": 15"
|
||||
"}";
|
||||
try{
|
||||
cereal::JSONInputArchive archive_in(string_stream_copy);
|
||||
orchestration_copy_policy.serialize(archive_in);
|
||||
} catch (cereal::Exception &e) {
|
||||
ASSERT_TRUE(false) << "Cereal threw an exception: " << e.what();
|
||||
}
|
||||
EXPECT_TRUE(orchestration_copy_policy == orchestration_policy);
|
||||
EXPECT_FALSE(orchestration_copy_policy != orchestration_policy);
|
||||
|
||||
OrchestrationPolicy orchestration_new_policy;
|
||||
stringstream string_stream_new;
|
||||
string_stream_new << "{"
|
||||
" \"fog-address\": \"http://10.0.0.18:801/control/\","
|
||||
" \"pulling-interval\": 20,"
|
||||
" \"error-pulling-interval\": 15"
|
||||
"}";
|
||||
try{
|
||||
cereal::JSONInputArchive archive_in(string_stream_new);
|
||||
orchestration_new_policy.serialize(archive_in);
|
||||
} catch (cereal::Exception &e) {
|
||||
ASSERT_TRUE(false) << "Cereal threw an exception: " << e.what();
|
||||
}
|
||||
EXPECT_FALSE(orchestration_new_policy == orchestration_policy);
|
||||
EXPECT_TRUE(orchestration_new_policy != orchestration_policy);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(PolicyTest, newOptionalFields)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{"
|
||||
" \"fog-address\": \"https://fog-api-gw-agents.cloud.ngen.checkpoint.com\","
|
||||
" \"pulling-interval\": 30,"
|
||||
" \"error-pulling-interval\": 10,"
|
||||
" \"agent-type\": \"arrow\""
|
||||
"}";
|
||||
|
||||
try {
|
||||
orchestrationPolicyToString(string_stream);
|
||||
} catch (cereal::Exception &e) {
|
||||
ASSERT_TRUE(false) << "Cereal threw an exception: " << e.what();
|
||||
}
|
||||
|
||||
EXPECT_EQ(10u, orchestration_policy.getErrorSleepInterval());
|
||||
EXPECT_EQ(30u, orchestration_policy.getSleepInterval());
|
||||
EXPECT_EQ("https://fog-api-gw-agents.cloud.ngen.checkpoint.com", orchestration_policy.getFogAddress());
|
||||
}
|
@@ -0,0 +1,484 @@
|
||||
#include "orchestration_status.h"
|
||||
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
|
||||
#include "cptest.h"
|
||||
#include "config.h"
|
||||
#include "config_component.h"
|
||||
#include "mock/mock_time_get.h"
|
||||
#include "mock/mock_orchestration_tools.h"
|
||||
#include "mock/mock_agent_details.h"
|
||||
#include "mock/mock_mainloop.h"
|
||||
#include "mock/mock_rest_api.h"
|
||||
|
||||
using namespace testing;
|
||||
using namespace std;
|
||||
using namespace chrono;
|
||||
|
||||
class OrchestrationStatusTest : public Test
|
||||
{
|
||||
public:
|
||||
~OrchestrationStatusTest() { Debug::setNewDefaultStdout(&cout); }
|
||||
|
||||
void
|
||||
init()
|
||||
{
|
||||
Debug::setUnitTestFlag(D_ORCHESTRATOR, Debug::DebugLevel::TRACE);
|
||||
Debug::setNewDefaultStdout(&capture_debug);
|
||||
CPTestTempfile status_file;
|
||||
file_path = status_file.fname;
|
||||
setConfiguration(file_path, "orchestration", "Orchestration status path");
|
||||
// Write orchestration status to file routine
|
||||
EXPECT_CALL(
|
||||
mock_mainloop,
|
||||
addRecurringRoutine(I_MainLoop::RoutineType::Timer, chrono::microseconds(5000000), _, _, false))
|
||||
.WillOnce(DoAll(SaveArg<2>(&routine), Return(1))
|
||||
);
|
||||
EXPECT_CALL(mock_tools, readFile(file_path)).WillOnce(Return(start_file_content));
|
||||
orchestration_status.init();
|
||||
}
|
||||
|
||||
string
|
||||
orchestrationStatusFileToString()
|
||||
{
|
||||
routine();
|
||||
ifstream status_file(file_path);
|
||||
stringstream string_stream;
|
||||
if (status_file.is_open()) {
|
||||
string line;
|
||||
bool is_first_line = true;
|
||||
while (getline(status_file, line)) {
|
||||
if (is_first_line) {
|
||||
is_first_line = false;
|
||||
} else {
|
||||
string_stream << endl;
|
||||
}
|
||||
string_stream << line;
|
||||
}
|
||||
status_file.close();
|
||||
}
|
||||
return string_stream.str();
|
||||
}
|
||||
|
||||
string
|
||||
buildOrchestrationStatusJSON(
|
||||
const string &last_update_attempt = "None",
|
||||
const string &last_update_status = "None",
|
||||
const string &last_update = "None",
|
||||
const string &last_manifest_update = "None",
|
||||
const string &policy_version = "",
|
||||
const string &last_policy_update = "None",
|
||||
const string &last_settings_update = "None",
|
||||
const string &upgrade_mode = "None",
|
||||
const string &fog_address = "None",
|
||||
const string ®istration_status = "None",
|
||||
const string &manifest_status = "None",
|
||||
const string ®istration_details_name = "",
|
||||
const string ®istration_details_type = "",
|
||||
const string ®istration_details_platform = "",
|
||||
const string ®istration_details_architecture = "",
|
||||
const string &agent_id = "None",
|
||||
const string &profile_id = "None",
|
||||
const string &tenant_id = "None"
|
||||
)
|
||||
{
|
||||
return "{\n"
|
||||
" \"Last update attempt\": \"" + last_update_attempt + "\",\n"
|
||||
" \"Last update status\": \"" + last_update_status + "\",\n"
|
||||
" \"Last update\": \"" + last_update + "\",\n"
|
||||
" \"Last manifest update\": \"" + last_manifest_update + "\",\n"
|
||||
" \"Policy version\": \"" + policy_version + "\",\n"
|
||||
" \"Last policy update\": \"" + last_policy_update + "\",\n"
|
||||
" \"Last settings update\": \"" + last_settings_update + "\",\n"
|
||||
" \"Upgrade mode\": \"" + upgrade_mode + "\",\n"
|
||||
" \"Fog address\": \"" + fog_address + "\",\n"
|
||||
" \"Registration status\": \"" + registration_status + "\",\n"
|
||||
" \"Registration details\": {\n"
|
||||
" \"Name\": \"" + registration_details_name + "\",\n"
|
||||
" \"Type\": \"" + registration_details_type + "\",\n"
|
||||
" \"Platform\": \"" + registration_details_platform + "\",\n"
|
||||
" \"Architecture\": \"" + registration_details_architecture + "\"\n"
|
||||
" },\n"
|
||||
" \"Agent ID\": \"" + agent_id + "\",\n"
|
||||
" \"Profile ID\": \"" + profile_id + "\",\n"
|
||||
" \"Tenant ID\": \"" + tenant_id + "\",\n"
|
||||
" \"Manifest status\": \"" + manifest_status + "\",\n"
|
||||
" \"Service policy\": {},\n"
|
||||
" \"Service settings\": {}\n"
|
||||
"}";
|
||||
}
|
||||
|
||||
::Environment env;
|
||||
ConfigComponent config;
|
||||
StrictMock<MockTimeGet> time;
|
||||
StrictMock<MockMainLoop> mock_mainloop;
|
||||
ostringstream capture_debug;
|
||||
StrictMock<MockOrchestrationTools> mock_tools;
|
||||
StrictMock<MockAgentDetails> mock_agent_details;
|
||||
OrchestrationStatus orchestration_status;
|
||||
I_OrchestrationStatus * i_orchestration_status =
|
||||
Singleton::Consume<I_OrchestrationStatus>::from(orchestration_status);
|
||||
string file_path;
|
||||
Maybe<string> start_file_content = genError("No file");
|
||||
I_MainLoop::Routine routine;
|
||||
};
|
||||
|
||||
TEST_F(OrchestrationStatusTest, doNothing)
|
||||
{
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationStatusTest, noFieldsValues)
|
||||
{
|
||||
init();
|
||||
auto result = orchestrationStatusFileToString();
|
||||
EXPECT_EQ(buildOrchestrationStatusJSON(), result);
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationStatusTest, recoverFields)
|
||||
{
|
||||
init();
|
||||
auto result = orchestrationStatusFileToString();
|
||||
i_orchestration_status->recoverFields();
|
||||
EXPECT_EQ(orchestrationStatusFileToString(), result);
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationStatusTest, loadFromFile)
|
||||
{
|
||||
Maybe<string> status = genError("No file");;
|
||||
CPTestTempfile status_file;
|
||||
file_path = status_file.fname;
|
||||
setConfiguration(file_path, "orchestration", "Orchestration status path");
|
||||
// Write to file routine
|
||||
EXPECT_CALL(
|
||||
mock_mainloop,
|
||||
addRecurringRoutine(I_MainLoop::RoutineType::Timer, chrono::microseconds(5000000), _, _, false)
|
||||
).Times(3).WillRepeatedly(DoAll(SaveArg<2>(&routine), Return(1)));
|
||||
|
||||
EXPECT_CALL(mock_tools, readFile(file_path)).Times(3).WillRepeatedly(Return(status));
|
||||
orchestration_status.init();
|
||||
status = orchestrationStatusFileToString();
|
||||
|
||||
orchestration_status.init();
|
||||
EXPECT_EQ(orchestrationStatusFileToString(), status.unpack());
|
||||
|
||||
EXPECT_CALL(time, getLocalTimeStr())
|
||||
.WillOnce(Return(string("attempt time")))
|
||||
.WillOnce(Return(string("current time")));
|
||||
i_orchestration_status->setLastUpdateAttempt();
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::LAST_UPDATE,
|
||||
OrchestrationStatusResult::SUCCESS
|
||||
);
|
||||
|
||||
status = orchestrationStatusFileToString();
|
||||
EXPECT_EQ(buildOrchestrationStatusJSON("attempt time", "Succeeded ", "current time"), status.unpack());
|
||||
|
||||
// Write status to file
|
||||
routine();
|
||||
|
||||
// Reload status from file and validate status
|
||||
orchestration_status.init();
|
||||
EXPECT_EQ(buildOrchestrationStatusJSON("attempt time", "Succeeded ", "current time"), status.unpack());
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationStatusTest, checkUpdateStatus)
|
||||
{
|
||||
init();
|
||||
EXPECT_CALL(time, getLocalTimeStr())
|
||||
.WillOnce(Return(string("attempt time")))
|
||||
.WillOnce(Return(string("current time")));
|
||||
|
||||
i_orchestration_status->setLastUpdateAttempt();
|
||||
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::LAST_UPDATE,
|
||||
OrchestrationStatusResult::SUCCESS
|
||||
);
|
||||
auto result = orchestrationStatusFileToString();
|
||||
EXPECT_EQ(buildOrchestrationStatusJSON("attempt time", "Succeeded ", "current time"), result);
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationStatusTest, recoveryFields)
|
||||
{
|
||||
init();
|
||||
CPTestTempfile status({""});
|
||||
setConfiguration(status.fname, "orchestration", "Orchestration status path");
|
||||
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::REGISTRATION,
|
||||
OrchestrationStatusResult::SUCCESS
|
||||
);
|
||||
const string agent_id = "AgentId";
|
||||
const string profile_id = "ProfileId";
|
||||
const string tenant_id = "TenantId";
|
||||
auto fog_addr = Maybe<string>(string("FogDomain"));
|
||||
|
||||
EXPECT_CALL(mock_agent_details, getAgentId()).WillOnce(Return(agent_id));
|
||||
EXPECT_CALL(mock_agent_details, getProfileId()).WillOnce(Return(profile_id));
|
||||
EXPECT_CALL(mock_agent_details, getTenantId()).WillOnce(Return(tenant_id));
|
||||
EXPECT_CALL(mock_agent_details, getFogDomain()).WillOnce(Return(fog_addr));
|
||||
i_orchestration_status->writeStatusToFile();
|
||||
EXPECT_THAT(capture_debug.str(), HasSubstr("Repairing status fields"));
|
||||
|
||||
EXPECT_EQ(i_orchestration_status->getAgentId(), agent_id);
|
||||
EXPECT_EQ(i_orchestration_status->getProfileId(), profile_id);
|
||||
EXPECT_EQ(i_orchestration_status->getTenantId(), tenant_id);
|
||||
EXPECT_EQ(i_orchestration_status->getFogAddress(), fog_addr.unpack());
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationStatusTest, updateAllLastUpdatesTypes)
|
||||
{
|
||||
init();
|
||||
EXPECT_CALL(time, getLocalTimeStr())
|
||||
.WillOnce(Return(string("attempt time")))
|
||||
.WillOnce(Return(string("current time")))
|
||||
.WillOnce(Return(string("current time001")));
|
||||
|
||||
i_orchestration_status->setLastUpdateAttempt();
|
||||
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::LAST_UPDATE,
|
||||
OrchestrationStatusResult::SUCCESS
|
||||
);
|
||||
i_orchestration_status->setIsConfigurationUpdated(
|
||||
EnumArray<OrchestrationStatusConfigType, bool>(true, false, false)
|
||||
);
|
||||
auto result = orchestrationStatusFileToString();
|
||||
EXPECT_EQ(buildOrchestrationStatusJSON("attempt time", "Succeeded ", "current time", "current time001"), result);
|
||||
|
||||
EXPECT_CALL(time, getLocalTimeStr())
|
||||
.Times(2)
|
||||
.WillRepeatedly(Return(string("current time002")));
|
||||
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::LAST_UPDATE,
|
||||
OrchestrationStatusResult::SUCCESS
|
||||
);
|
||||
i_orchestration_status->setIsConfigurationUpdated(
|
||||
EnumArray<OrchestrationStatusConfigType, bool>(true, true, false)
|
||||
);
|
||||
result = orchestrationStatusFileToString();
|
||||
EXPECT_EQ(
|
||||
buildOrchestrationStatusJSON(
|
||||
"attempt time",
|
||||
"Succeeded ",
|
||||
"current time002",
|
||||
"current time002",
|
||||
"",
|
||||
"current time002"
|
||||
),
|
||||
result
|
||||
);
|
||||
|
||||
EXPECT_CALL(time, getLocalTimeStr())
|
||||
.Times(2)
|
||||
.WillRepeatedly(Return(string("current time003")));
|
||||
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::LAST_UPDATE,
|
||||
OrchestrationStatusResult::SUCCESS
|
||||
);
|
||||
i_orchestration_status->setIsConfigurationUpdated(
|
||||
EnumArray<OrchestrationStatusConfigType, bool>(true, true, true)
|
||||
);
|
||||
result = orchestrationStatusFileToString();
|
||||
EXPECT_EQ(
|
||||
buildOrchestrationStatusJSON(
|
||||
"attempt time",
|
||||
"Succeeded ",
|
||||
"current time003",
|
||||
"current time003",
|
||||
"",
|
||||
"current time003",
|
||||
"current time003"
|
||||
),
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationStatusTest, errorInRegistrationAndMainfest)
|
||||
{
|
||||
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")));
|
||||
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::LAST_UPDATE,
|
||||
OrchestrationStatusResult::SUCCESS
|
||||
);
|
||||
i_orchestration_status->setIsConfigurationUpdated(
|
||||
EnumArray<OrchestrationStatusConfigType, bool>(true, true, true)
|
||||
);
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::LAST_UPDATE,
|
||||
OrchestrationStatusResult::FAILED,
|
||||
last_update_error
|
||||
);
|
||||
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);
|
||||
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::REGISTRATION,
|
||||
OrchestrationStatusResult::FAILED,
|
||||
registar_error
|
||||
);
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::MANIFEST,
|
||||
OrchestrationStatusResult::FAILED,
|
||||
manifest_error
|
||||
);
|
||||
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: " + registar_error,
|
||||
"Failed. Reason: " + manifest_error
|
||||
),
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationStatusTest, setAllFields)
|
||||
{
|
||||
init();
|
||||
string fog_address = "http://fog.address";
|
||||
EXPECT_CALL(time, getLocalTimeStr())
|
||||
.Times(3)
|
||||
.WillRepeatedly(Return(string("current time")));
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::LAST_UPDATE,
|
||||
OrchestrationStatusResult::SUCCESS
|
||||
);
|
||||
i_orchestration_status->setIsConfigurationUpdated(
|
||||
EnumArray<OrchestrationStatusConfigType, bool>(true, true, true)
|
||||
);
|
||||
i_orchestration_status->setRegistrationDetails("name", "type", "platform", "arch");
|
||||
i_orchestration_status->setAgentDetails("id", "profile", "tenant");
|
||||
i_orchestration_status->setFogAddress("http://fog.address");
|
||||
i_orchestration_status->setPolicyVersion("12");
|
||||
i_orchestration_status->setAgentType("test_type");
|
||||
i_orchestration_status->setUpgradeMode("Test Mode");
|
||||
i_orchestration_status->setRegistrationStatus("Succeeded");
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::REGISTRATION,
|
||||
OrchestrationStatusResult::SUCCESS
|
||||
);
|
||||
i_orchestration_status->setFieldStatus(
|
||||
OrchestrationStatusFieldType::MANIFEST,
|
||||
OrchestrationStatusResult::SUCCESS
|
||||
);
|
||||
|
||||
string non_empty_conf = "{x:y}";
|
||||
string curr_mock_path = "path";
|
||||
EXPECT_CALL(mock_tools, readFile(curr_mock_path)).WillRepeatedly(Return(non_empty_conf));
|
||||
EXPECT_CALL(mock_tools, readFile(string("new_path"))).WillOnce(Return(string("{}")));
|
||||
|
||||
i_orchestration_status->setServiceConfiguration(
|
||||
"service_a", "path", OrchestrationStatusConfigType::SETTINGS
|
||||
);
|
||||
i_orchestration_status->setServiceConfiguration(
|
||||
"service_b", "path", OrchestrationStatusConfigType::POLICY
|
||||
);
|
||||
i_orchestration_status->setServiceConfiguration(
|
||||
"service_c", "path", OrchestrationStatusConfigType::POLICY
|
||||
);
|
||||
i_orchestration_status->setServiceConfiguration(
|
||||
"service_c", "new_path", OrchestrationStatusConfigType::POLICY
|
||||
);
|
||||
i_orchestration_status->setLastUpdateAttempt();
|
||||
|
||||
auto result = orchestrationStatusFileToString();
|
||||
|
||||
string expected = "{\n"
|
||||
" \"Last update attempt\": \"current time\",\n"
|
||||
" \"Last update status\": \"Succeeded \",\n"
|
||||
" \"Last update\": \"current time\",\n"
|
||||
" \"Last manifest update\": \"current time\",\n"
|
||||
" \"Policy version\": \"12\",\n"
|
||||
" \"Last policy update\": \"current time\",\n"
|
||||
" \"Last settings update\": \"current time\",\n"
|
||||
" \"Upgrade mode\": \"Test Mode\",\n"
|
||||
" \"Fog address\": \"http://fog.address\",\n"
|
||||
" \"Registration status\": \"Succeeded \",\n"
|
||||
" \"Registration details\": {\n"
|
||||
" \"Name\": \"name\",\n"
|
||||
" \"Type\": \"test_type\",\n"
|
||||
" \"Platform\": \"platform\",\n"
|
||||
" \"Architecture\": \"arch\"\n"
|
||||
" },\n"
|
||||
" \"Agent ID\": \"id\",\n"
|
||||
" \"Profile ID\": \"profile\",\n"
|
||||
" \"Tenant ID\": \"tenant\",\n"
|
||||
" \"Manifest status\": \"Succeeded \",\n"
|
||||
" \"Service policy\": {\n"
|
||||
" \"service_b\": \"path\"\n"
|
||||
" },\n"
|
||||
" \"Service settings\": {\n"
|
||||
" \"service_a\": \"path\"\n"
|
||||
" }\n"
|
||||
"}";
|
||||
EXPECT_EQ(expected, result);
|
||||
|
||||
// Now lets check load from file
|
||||
routine();
|
||||
EXPECT_EQ(expected, orchestrationStatusFileToString());
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_mainloop,
|
||||
addRecurringRoutine(I_MainLoop::RoutineType::Timer, chrono::microseconds(5000000), _, _, false))
|
||||
.WillOnce(DoAll(SaveArg<2>(&routine), Return(1)));
|
||||
EXPECT_CALL(mock_tools, readFile(file_path)).Times(1).WillOnce(Return(expected));
|
||||
orchestration_status.init();
|
||||
EXPECT_EQ(expected, orchestrationStatusFileToString());
|
||||
|
||||
map<string, string> service_map_a = {{"service_a", "path"}};
|
||||
map<string, string> service_map_b = {{"service_b", "path"}};
|
||||
|
||||
string agent_details =
|
||||
"\n Name: name"
|
||||
"\n Type: test_type"
|
||||
"\n Platform: platform"
|
||||
"\n Architecture: arch";
|
||||
|
||||
EXPECT_EQ(i_orchestration_status->getLastUpdateAttempt(), "current time");
|
||||
EXPECT_EQ(i_orchestration_status->getUpdateStatus(), "Succeeded ");;
|
||||
EXPECT_EQ(i_orchestration_status->getUpdateTime(), "current time");
|
||||
EXPECT_EQ(i_orchestration_status->getLastManifestUpdate(), "current time");
|
||||
EXPECT_EQ(i_orchestration_status->getPolicyVersion(), "12");
|
||||
EXPECT_EQ(i_orchestration_status->getLastPolicyUpdate(), "current time");
|
||||
EXPECT_EQ(i_orchestration_status->getLastSettingsUpdate(), "current time");
|
||||
EXPECT_EQ(i_orchestration_status->getUpgradeMode(), "Test Mode");
|
||||
EXPECT_EQ(i_orchestration_status->getFogAddress(), "http://fog.address");
|
||||
EXPECT_EQ(i_orchestration_status->getRegistrationStatus(), "Succeeded ");
|
||||
EXPECT_EQ(i_orchestration_status->getAgentId(), "id");
|
||||
EXPECT_EQ(i_orchestration_status->getProfileId(), "profile");
|
||||
EXPECT_EQ(i_orchestration_status->getTenantId(), "tenant");
|
||||
EXPECT_EQ(i_orchestration_status->getManifestStatus(), "Succeeded ");
|
||||
EXPECT_EQ(i_orchestration_status->getServicePolicies(), service_map_b);
|
||||
EXPECT_EQ(i_orchestration_status->getServiceSettings(), service_map_a);
|
||||
EXPECT_EQ(i_orchestration_status->getRegistrationDetails(), agent_details);
|
||||
}
|
236
components/security_apps/orchestration/modules/modules_ut/package_ut.cc
Executable file
236
components/security_apps/orchestration/modules/modules_ut/package_ut.cc
Executable file
@@ -0,0 +1,236 @@
|
||||
#include "package.h"
|
||||
|
||||
#include "cptest.h"
|
||||
#include "cereal/types/string.hpp"
|
||||
#include "cereal/archives/json.hpp"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
|
||||
using namespace testing;
|
||||
using namespace std;
|
||||
|
||||
class PackageTest : public Test
|
||||
{
|
||||
public:
|
||||
PackageTest() {}
|
||||
|
||||
bool
|
||||
load(stringstream &string_stream, Package &package)
|
||||
{
|
||||
try {
|
||||
cereal::JSONInputArchive archive_in(string_stream);
|
||||
package.serialize(archive_in);
|
||||
} catch (const cereal::Exception &) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
write(const string &path, Package &package)
|
||||
{
|
||||
std::ofstream os(path);
|
||||
cereal::JSONOutputArchive archive_out(os);
|
||||
package.serialize(archive_out);
|
||||
}
|
||||
|
||||
string
|
||||
readFile(const string &path)
|
||||
{
|
||||
ifstream text_file(path);
|
||||
stringstream buffer;
|
||||
buffer << text_file.rdbuf();
|
||||
return buffer.str();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(PackageTest, doNothing)
|
||||
{
|
||||
}
|
||||
|
||||
TEST_F(PackageTest, serializationFromString)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{"
|
||||
" \"version\": \"c\","
|
||||
" \"download-path\": \"https://a/install_orchestration.sh\",\n"
|
||||
" \"relative-path\": \"/install_orchestration.sh\",\n"
|
||||
" \"name\": \"orchestration\","
|
||||
" \"checksum-type\": \"sha1sum\","
|
||||
" \"checksum\": \"8d4a5709673a05b380ba7d6567e28910019118f5\","
|
||||
" \"package-type\": \"service\","
|
||||
" \"require\": []"
|
||||
"}";
|
||||
Package package;
|
||||
EXPECT_EQ(true, load(string_stream, package));
|
||||
|
||||
vector<string> links = { "https://10.0.0.18/install_orchestration.sh", "ftp://172.23.92.135/policy.txt" };
|
||||
|
||||
EXPECT_EQ("orchestration", package.getName());
|
||||
EXPECT_EQ(Package::ChecksumTypes::SHA1, package.getChecksumType());
|
||||
EXPECT_EQ("8d4a5709673a05b380ba7d6567e28910019118f5", package.getChecksum());
|
||||
EXPECT_EQ("orchestration", package.getName());
|
||||
EXPECT_EQ("c", package.getVersion());
|
||||
EXPECT_EQ(Package::PackageType::Service, package.getType());
|
||||
EXPECT_TRUE(package.isInstallable().ok());
|
||||
}
|
||||
|
||||
TEST_F(PackageTest, writeAsJson)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{\n"
|
||||
" \"download-path\": \"https://a/install_orchestration.sh\",\n"
|
||||
" \"relative-path\": \"/install_orchestration.sh\",\n"
|
||||
" \"version\": \"c\",\n"
|
||||
" \"name\": \"orchestration\",\n"
|
||||
" \"checksum-type\": \"sha1sum\",\n"
|
||||
" \"checksum\": \"8d4a5709673a05b380ba7d6567e28910019118f5\",\n"
|
||||
" \"package-type\": \"service\"\n"
|
||||
"}";
|
||||
Package package;
|
||||
EXPECT_EQ(true, load(string_stream, package));
|
||||
|
||||
vector<string> links = { "https://10.0.0.18/install_orchestration.sh", "ftp://172.23.92.135/policy.txt" };
|
||||
|
||||
EXPECT_EQ("orchestration", package.getName());
|
||||
EXPECT_EQ(Package::ChecksumTypes::SHA1, package.getChecksumType());
|
||||
EXPECT_EQ("8d4a5709673a05b380ba7d6567e28910019118f5", package.getChecksum());
|
||||
EXPECT_EQ("orchestration", package.getName());
|
||||
EXPECT_EQ("c", package.getVersion());
|
||||
EXPECT_EQ(Package::PackageType::Service, package.getType());
|
||||
EXPECT_TRUE(package.isInstallable().ok());
|
||||
|
||||
write("service.json", package);
|
||||
string data = readFile("service.json");
|
||||
EXPECT_EQ(string_stream.str(), data);
|
||||
}
|
||||
|
||||
TEST_F(PackageTest, eqService)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{\n"
|
||||
" \"download-path\": \"https://a/install_orchestration.sh\",\n"
|
||||
" \"relative-path\": \"/install_orchestration.sh\",\n"
|
||||
" \"version\": \"c\",\n"
|
||||
" \"name\": \"orchestration\",\n"
|
||||
" \"checksum-type\": \"sha1sum\",\n"
|
||||
" \"checksum\": \"8d4a5709673a05b380ba7d6567e28910019118f5\",\n"
|
||||
" \"package-type\": \"service\"\n"
|
||||
"}";
|
||||
Package package;
|
||||
Package package2;
|
||||
EXPECT_TRUE(load(string_stream, package));
|
||||
string_stream.clear();
|
||||
string_stream << "{\n"
|
||||
" \"download-path\": \"https://a/install_orchestration.sh\",\n"
|
||||
" \"relative-path\": \"/install_orchestration.sh\",\n"
|
||||
" \"version\": \"c\",\n"
|
||||
" \"name\": \"orchestration\",\n"
|
||||
" \"checksum-type\": \"sha1sum\",\n"
|
||||
" \"checksum\": \"8d4a5709673a05b380ba7d6567e28910000000000\",\n"
|
||||
" \"package-type\": \"service\"\n"
|
||||
"}";
|
||||
EXPECT_TRUE(load(string_stream, package));
|
||||
EXPECT_TRUE(package != package2);
|
||||
}
|
||||
|
||||
TEST_F(PackageTest, changeDir)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{\n"
|
||||
" \"download-path\": \"https://a/install_orchestration.sh\",\n"
|
||||
" \"relative-path\": \"/install_orchestration.sh\",\n"
|
||||
" \"version\": \"c\",\n"
|
||||
" \"name\": \"../..\",\n"
|
||||
" \"checksum-type\": \"sha1sum\",\n"
|
||||
" \"checksum\": \"8d4a5709673a05b380ba7d6567e28910019118f5\",\n"
|
||||
" \"package-type\": \"service\"\n"
|
||||
"}";
|
||||
Package package;
|
||||
EXPECT_FALSE(load(string_stream, package));
|
||||
}
|
||||
|
||||
TEST_F(PackageTest, mkdirCommand)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{\n"
|
||||
" \"download-path\": \"https://a/install_orchestration.sh\",\n"
|
||||
" \"relative-path\": \"/install_orchestration.sh\",\n"
|
||||
" \"version\": \"c\",\n"
|
||||
" \"name\": \"mkdir ../../something\",\n"
|
||||
" \"checksum-type\": \"sha1sum\",\n"
|
||||
" \"checksum\": \"8d4a5709673a05b380ba7d6567e28910019118f5\",\n"
|
||||
" \"package-type\": \"service\"\n"
|
||||
"}";
|
||||
Package package;
|
||||
EXPECT_FALSE(load(string_stream, package));
|
||||
}
|
||||
|
||||
TEST_F(PackageTest, badPackageName)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{\n"
|
||||
" \"download-path\": \"https://a/install_orchestration.sh\",\n"
|
||||
" \"relative-path\": \"/install_orchestration.sh\",\n"
|
||||
" \"version\": \"c\",\n"
|
||||
" \"name\": \"- - - - - -\",\n"
|
||||
" \"checksum-type\": \"sha1sum\",\n"
|
||||
" \"checksum\": \"8d4a5709673a05b380ba7d6567e28910019118f5\",\n"
|
||||
" \"package-type\": \"service\"\n"
|
||||
"}";
|
||||
Package package;
|
||||
EXPECT_FALSE(load(string_stream, package));
|
||||
}
|
||||
|
||||
TEST_F(PackageTest, anyOrder)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{\n"
|
||||
" \"name\": \"asdQwe\",\n"
|
||||
" \"relative-path\": \"/install_orchestration.sh\",\n"
|
||||
" \"version\": \"c\",\n"
|
||||
" \"download-path\": \"https://a/install_orchestration.sh\",\n"
|
||||
" \"checksum\": \"8d4a5709673a05b380ba7d6567e28910019118f5\",\n"
|
||||
" \"package-type\": \"service\",\n"
|
||||
" \"checksum-type\": \"sha1sum\"\n"
|
||||
"}";
|
||||
Package package;
|
||||
EXPECT_TRUE(load(string_stream, package));
|
||||
}
|
||||
|
||||
TEST_F(PackageTest, anyOrderWithRequire)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{\n"
|
||||
" \"require\": [],\n"
|
||||
" \"name\": \"asdQwe\",\n"
|
||||
" \"version\": \"c\",\n"
|
||||
" \"relative-path\": \"/install_orchestration.sh\",\n"
|
||||
" \"download-path\": \"https://a/install_orchestration.sh\",\n"
|
||||
" \"checksum\": \"8d4a5709673a05b380ba7d6567e28910019118f5\",\n"
|
||||
" \"package-type\": \"service\",\n"
|
||||
" \"checksum-type\": \"sha1sum\"\n"
|
||||
"}";
|
||||
Package package;
|
||||
EXPECT_TRUE(load(string_stream, package));
|
||||
}
|
||||
|
||||
TEST_F(PackageTest, uninstallablePackage)
|
||||
{
|
||||
stringstream string_stream;
|
||||
string_stream << "{\n"
|
||||
" \"name\": \"waap\",\n"
|
||||
" \"version\": \"\",\n"
|
||||
" \"download-path\": \"\",\n"
|
||||
" \"relative-path\": \"\",\n"
|
||||
" \"checksum\": \"\",\n"
|
||||
" \"package-type\": \"service\",\n"
|
||||
" \"checksum-type\": \"sha1sum\",\n"
|
||||
" \"status\": false,\n"
|
||||
" \"message\": \"This security app isn't valid for this agent\"\n"
|
||||
"}";
|
||||
Package package;
|
||||
EXPECT_TRUE(load(string_stream, package));
|
||||
EXPECT_THAT(package.isInstallable(), IsError("This security app isn't valid for this agent"));
|
||||
}
|
117
components/security_apps/orchestration/modules/modules_ut/url_parser_ut.cc
Executable file
117
components/security_apps/orchestration/modules/modules_ut/url_parser_ut.cc
Executable file
@@ -0,0 +1,117 @@
|
||||
#include "url_parser.h"
|
||||
|
||||
#include "cptest.h"
|
||||
#include "mock/mock_orchestration_tools.h"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
using namespace testing;
|
||||
using namespace std;
|
||||
|
||||
class URLParserTest : public Test
|
||||
{
|
||||
public:
|
||||
URLParserTest() {}
|
||||
|
||||
StrictMock<MockOrchestrationTools> mock_orchestration_tools;
|
||||
};
|
||||
|
||||
TEST_F(URLParserTest, doNothing)
|
||||
{
|
||||
}
|
||||
|
||||
TEST_F(URLParserTest, parseHTTP)
|
||||
{
|
||||
URLParser link("http://172.23.92.180:180/something");
|
||||
|
||||
EXPECT_FALSE(link.isOverSSL());
|
||||
EXPECT_EQ("180", link.getPort());
|
||||
EXPECT_EQ("/something", link.getQuery());
|
||||
}
|
||||
|
||||
TEST_F(URLParserTest, parseHTTPS)
|
||||
{
|
||||
URLParser link("https://172.23.92.180:180/something");
|
||||
|
||||
EXPECT_TRUE(link.isOverSSL());
|
||||
EXPECT_EQ("180", link.getPort());
|
||||
EXPECT_EQ("/something", link.getQuery());
|
||||
}
|
||||
|
||||
TEST_F(URLParserTest, parseAWS)
|
||||
{
|
||||
URLParser link("https://a58efa94efdf711e8a6540620a59b447-1878332922.eu-west-1.elb.amazonaws.com/");
|
||||
|
||||
EXPECT_TRUE(link.isOverSSL());
|
||||
EXPECT_EQ("443", link.getPort());
|
||||
EXPECT_EQ("a58efa94efdf711e8a6540620a59b447-1878332922.eu-west-1.elb.amazonaws.com", link.getBaseURL().unpack());
|
||||
EXPECT_EQ("", link.getQuery());
|
||||
}
|
||||
|
||||
TEST_F(URLParserTest, parseAWSWithoutSlash)
|
||||
{
|
||||
URLParser link("https://a58efa94efdf711e8a6540620a59b447-1878332922.eu-west-1.elb.amazonaws.com");
|
||||
|
||||
EXPECT_TRUE(link.isOverSSL());
|
||||
EXPECT_EQ("443", link.getPort());
|
||||
EXPECT_EQ("a58efa94efdf711e8a6540620a59b447-1878332922.eu-west-1.elb.amazonaws.com", link.getBaseURL().unpack());
|
||||
EXPECT_EQ("", link.getQuery());
|
||||
}
|
||||
|
||||
TEST_F(URLParserTest, protocolIsMissing)
|
||||
{
|
||||
// HTTPS is set by default when protocol is not present in URL.
|
||||
URLParser link("a58efa94efdf711e8a6540620a59b447-1878332922.eu-west-1.elb.amazonaws.com");
|
||||
|
||||
EXPECT_EQ(link.getBaseURL().unpack(), "a58efa94efdf711e8a6540620a59b447-1878332922.eu-west-1.elb.amazonaws.com");
|
||||
EXPECT_TRUE(link.isOverSSL());
|
||||
EXPECT_EQ("443", link.getPort());
|
||||
EXPECT_EQ("", link.getQuery());
|
||||
}
|
||||
|
||||
TEST_F(URLParserTest, parseBadURL)
|
||||
{
|
||||
URLParser link("http://this_is_not_https_site.com/something");
|
||||
|
||||
EXPECT_FALSE(link.isOverSSL());
|
||||
EXPECT_EQ("80", link.getPort());
|
||||
EXPECT_EQ("this_is_not_https_site.com", link.getBaseURL().unpack());
|
||||
EXPECT_EQ("/something", link.getQuery());
|
||||
}
|
||||
|
||||
TEST_F(URLParserTest, parseNothing)
|
||||
{
|
||||
URLParser link("");
|
||||
EXPECT_FALSE(link.getBaseURL().ok());
|
||||
EXPECT_TRUE(link.isOverSSL());
|
||||
EXPECT_EQ("443", link.getPort());
|
||||
EXPECT_EQ("", link.getQuery());
|
||||
}
|
||||
|
||||
TEST_F(URLParserTest, copyCtr)
|
||||
{
|
||||
URLParser link("");
|
||||
URLParser copy_link = link;
|
||||
EXPECT_TRUE(copy_link.isOverSSL());
|
||||
EXPECT_EQ("443", copy_link.getPort());
|
||||
EXPECT_EQ("", copy_link.getQuery());
|
||||
}
|
||||
|
||||
TEST_F(URLParserTest, printTest)
|
||||
{
|
||||
string url_path = "this_is_test_url";
|
||||
URLParser link(url_path);
|
||||
EXPECT_EQ("https://" + url_path + ":443", link.toString());
|
||||
stringstream ss;
|
||||
ss << link;
|
||||
EXPECT_EQ("https://" + url_path + ":443", ss.str());
|
||||
}
|
||||
TEST_F(URLParserTest, setQuery)
|
||||
{
|
||||
string url_path = "this_is_test_url/test.sh";
|
||||
URLParser link(url_path);
|
||||
EXPECT_EQ("https://" + url_path + ":443", link.toString());
|
||||
link.setQuery("/new-query");
|
||||
EXPECT_EQ("https://this_is_test_url/new-query:443", link.toString());
|
||||
}
|
64
components/security_apps/orchestration/modules/orchestration_policy.cc
Executable file
64
components/security_apps/orchestration/modules/orchestration_policy.cc
Executable file
@@ -0,0 +1,64 @@
|
||||
// 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 "orchestration_policy.h"
|
||||
|
||||
#include "sasal.h"
|
||||
|
||||
SASAL_START // Orchestration - Modules
|
||||
|
||||
using namespace std;
|
||||
using namespace cereal;
|
||||
|
||||
const string &
|
||||
OrchestrationPolicy::getFogAddress() const
|
||||
{
|
||||
return fog_address;
|
||||
}
|
||||
|
||||
const unsigned long &
|
||||
OrchestrationPolicy::getSleepInterval() const
|
||||
{
|
||||
return sleep_interval;
|
||||
}
|
||||
|
||||
const unsigned long &
|
||||
OrchestrationPolicy::getErrorSleepInterval() const
|
||||
{
|
||||
return error_sleep_interval;
|
||||
}
|
||||
|
||||
void
|
||||
OrchestrationPolicy::serialize(JSONInputArchive &archive)
|
||||
{
|
||||
// Split it, so the order doesn't matter.
|
||||
archive(make_nvp("fog-address", fog_address));
|
||||
archive(make_nvp("pulling-interval", sleep_interval));
|
||||
archive(make_nvp("error-pulling-interval", error_sleep_interval));
|
||||
}
|
||||
|
||||
bool
|
||||
OrchestrationPolicy::operator==(const OrchestrationPolicy &other) const
|
||||
{
|
||||
return error_sleep_interval == other.error_sleep_interval &&
|
||||
sleep_interval == other.sleep_interval &&
|
||||
fog_address == other.fog_address;
|
||||
}
|
||||
|
||||
bool
|
||||
OrchestrationPolicy::operator!=(const OrchestrationPolicy &other) const
|
||||
{
|
||||
return !((*this) == other);
|
||||
}
|
||||
|
||||
SASAL_END
|
685
components/security_apps/orchestration/modules/orchestration_status.cc
Executable file
685
components/security_apps/orchestration/modules/orchestration_status.cc
Executable file
@@ -0,0 +1,685 @@
|
||||
// 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 "orchestration_status.h"
|
||||
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <algorithm>
|
||||
|
||||
#include "debug.h"
|
||||
#include "config.h"
|
||||
#include "sasal.h"
|
||||
|
||||
using namespace cereal;
|
||||
using namespace std;
|
||||
using namespace chrono;
|
||||
|
||||
USE_DEBUG_FLAG(D_ORCHESTRATOR);
|
||||
|
||||
SASAL_START // Orchestration - Modules
|
||||
|
||||
class RegistrationDetails
|
||||
{
|
||||
public:
|
||||
RegistrationDetails() = default;
|
||||
RegistrationDetails(const RegistrationDetails &) = default;
|
||||
RegistrationDetails(RegistrationDetails &&) = default;
|
||||
RegistrationDetails(
|
||||
string name,
|
||||
string type,
|
||||
string platform,
|
||||
string architecture)
|
||||
:
|
||||
name(name),
|
||||
type(type),
|
||||
platform(platform),
|
||||
architecture(architecture)
|
||||
{}
|
||||
|
||||
void
|
||||
serialize(cereal::JSONOutputArchive &archive)
|
||||
{
|
||||
if (type == "InfinityNextGateway") {
|
||||
type = "AppSecGateway";
|
||||
}
|
||||
archive(
|
||||
cereal::make_nvp("Name", name),
|
||||
cereal::make_nvp("Type", type),
|
||||
cereal::make_nvp("Platform", platform),
|
||||
cereal::make_nvp("Architecture", architecture)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
serialize(cereal::JSONInputArchive &archive)
|
||||
{
|
||||
archive(
|
||||
cereal::make_nvp("Name", name),
|
||||
cereal::make_nvp("Type", type),
|
||||
cereal::make_nvp("Platform", platform),
|
||||
cereal::make_nvp("Architecture", architecture)
|
||||
);
|
||||
if (type == "InfinityNextGateway") {
|
||||
type = "AppSecGateway";
|
||||
}
|
||||
}
|
||||
|
||||
RegistrationDetails & operator=(const RegistrationDetails &) = default;
|
||||
RegistrationDetails & operator=(RegistrationDetails &&) = default;
|
||||
void setAgentType(const string &_type) { type = _type; }
|
||||
|
||||
string
|
||||
toString() const
|
||||
{
|
||||
return
|
||||
"\n Name: " + name +
|
||||
"\n Type: " + type +
|
||||
"\n Platform: " + platform +
|
||||
"\n Architecture: " + architecture;
|
||||
}
|
||||
|
||||
private:
|
||||
string name;
|
||||
string type;
|
||||
string platform;
|
||||
string architecture;
|
||||
};
|
||||
|
||||
class Status
|
||||
{
|
||||
public:
|
||||
Status() = default;
|
||||
Status(const Status &) = default;
|
||||
Status(Status &&) = default;
|
||||
|
||||
Status & operator=(Status &&from) = default;
|
||||
Status & operator=(const Status &from)
|
||||
{
|
||||
last_update_status = from.last_update_status;
|
||||
last_update_time = from.last_update_time;
|
||||
last_update_attempt = from.last_update_attempt;
|
||||
last_manifest_update = from.last_manifest_update;
|
||||
policy_version = from.policy_version;
|
||||
last_policy_update = from.last_policy_update;
|
||||
last_settings_update = from.last_settings_update;
|
||||
upgrade_mode = from.upgrade_mode;
|
||||
fog_address = from.fog_address;
|
||||
registration_status = from.registration_status;
|
||||
manifest_status = from.manifest_status;
|
||||
agent_id = from.agent_id;
|
||||
profile_id = from.profile_id;
|
||||
tenant_id = from.tenant_id;
|
||||
registration_details = from.registration_details;
|
||||
service_policies = from.service_policies;
|
||||
service_settings = from.service_settings;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const string & getLastUpdateAttempt() const { return last_update_attempt; }
|
||||
const string & getUpdateStatus() const { return last_update_status; }
|
||||
const string & getUpdateTime() const { return last_update_time; }
|
||||
const string & getLastManifestUpdate() const { return last_manifest_update; }
|
||||
const string & getPolicyVersion() const { return policy_version; }
|
||||
const string & getLastPolicyUpdate() const { return last_policy_update; }
|
||||
const string & getLastSettingsUpdate() const { return last_settings_update; }
|
||||
const string & getUpgradeMode() const { return upgrade_mode; }
|
||||
const string & getFogAddress() const { return fog_address; }
|
||||
const string & getRegistrationStatus() const { return registration_status; }
|
||||
const string & getAgentId() const { return agent_id; }
|
||||
const string & getProfileId() const { return profile_id; }
|
||||
const string & getTenantId() const { return tenant_id; }
|
||||
const string & getManifestStatus() const { return manifest_status; }
|
||||
const string & getManifestError() const { return manifest_error; }
|
||||
const RegistrationDetails & getRegistrationDetails() const { return registration_details; }
|
||||
const map<string, string> & getServicePolicies() const { return service_policies; }
|
||||
const map<string, string> & getServiceSettings() const { return service_settings; }
|
||||
|
||||
void
|
||||
insertServicePolicy(const string &key, const string &value)
|
||||
{
|
||||
service_policies.insert(make_pair(key, value));
|
||||
}
|
||||
|
||||
void
|
||||
eraseServicePolicy(const string &key)
|
||||
{
|
||||
service_policies.erase(key);
|
||||
}
|
||||
|
||||
void
|
||||
insertServiceSetting(const string &key, const string &value)
|
||||
{
|
||||
service_settings.insert(make_pair(key, value));
|
||||
}
|
||||
|
||||
void
|
||||
eraseServiceSetting(const string &key)
|
||||
{
|
||||
service_settings.erase(key);
|
||||
}
|
||||
|
||||
void
|
||||
setIsConfigurationUpdated(
|
||||
EnumArray<OrchestrationStatusConfigType, bool> config_types,
|
||||
const string ¤t_time
|
||||
)
|
||||
{
|
||||
if (config_types[OrchestrationStatusConfigType::MANIFEST]) last_manifest_update = current_time;
|
||||
if (config_types[OrchestrationStatusConfigType::POLICY]) last_policy_update = current_time;
|
||||
if (config_types[OrchestrationStatusConfigType::SETTINGS]) last_settings_update = current_time;
|
||||
}
|
||||
|
||||
void
|
||||
setPolicyVersion(const string &_policy_version)
|
||||
{
|
||||
policy_version = _policy_version;
|
||||
}
|
||||
|
||||
void
|
||||
setRegistrationStatus(const string &_reg_status)
|
||||
{
|
||||
registration_status = _reg_status;
|
||||
}
|
||||
|
||||
void
|
||||
setUpgradeMode(const string &_upgrade_mode)
|
||||
{
|
||||
upgrade_mode = _upgrade_mode;
|
||||
}
|
||||
|
||||
void
|
||||
setAgentType(const string &_agent_type)
|
||||
{
|
||||
registration_details.setAgentType(_agent_type);
|
||||
}
|
||||
|
||||
void
|
||||
setAgentDetails(
|
||||
const string &_agent_id,
|
||||
const string &_profile_id,
|
||||
const string &_tenant_id)
|
||||
{
|
||||
agent_id = _agent_id;
|
||||
profile_id = _profile_id;
|
||||
tenant_id = _tenant_id;
|
||||
}
|
||||
|
||||
void
|
||||
setLastUpdateAttempt(const string &_last_update_attempt)
|
||||
{
|
||||
last_update_attempt = _last_update_attempt;
|
||||
}
|
||||
|
||||
void
|
||||
setFogAddress(const string &_fog_address)
|
||||
{
|
||||
fog_address = _fog_address;
|
||||
}
|
||||
|
||||
void
|
||||
setRegistrationDetails(
|
||||
const string &name,
|
||||
const string &type,
|
||||
const string &platform,
|
||||
const string &arch)
|
||||
{
|
||||
registration_details = RegistrationDetails(name, type, platform, arch);
|
||||
}
|
||||
|
||||
void
|
||||
setManifestStatus(const string &_manifest_status)
|
||||
{
|
||||
manifest_status = _manifest_status;
|
||||
}
|
||||
|
||||
void
|
||||
setManifestError(const string &error)
|
||||
{
|
||||
manifest_error = error;
|
||||
}
|
||||
|
||||
void
|
||||
setLastUpdateTime(const string &_last_update_time)
|
||||
{
|
||||
last_update_time = _last_update_time;
|
||||
}
|
||||
|
||||
void
|
||||
setLastUpdateStatus(const string &_last_update_status)
|
||||
{
|
||||
last_update_status = _last_update_status;
|
||||
}
|
||||
|
||||
void
|
||||
initValues()
|
||||
{
|
||||
last_update_attempt = "None";
|
||||
last_update_time = "None";
|
||||
last_update_status = "None";
|
||||
last_manifest_update = "None";
|
||||
last_policy_update = "None";
|
||||
last_settings_update = "None";
|
||||
fog_address = "None";
|
||||
agent_id = "None";
|
||||
profile_id = "None";
|
||||
tenant_id = "None";
|
||||
registration_status = "None";
|
||||
manifest_status = "None";
|
||||
upgrade_mode = "None";
|
||||
}
|
||||
|
||||
void
|
||||
recoverFields()
|
||||
{
|
||||
auto success_status = "Succeeded";
|
||||
if (fog_address == "None" && registration_status.find(success_status) != string::npos) {
|
||||
auto agent_details = Singleton::Consume<I_AgentDetails>::by<OrchestrationStatus>();
|
||||
dbgWarning(D_ORCHESTRATOR) << "Repairing status fields";
|
||||
agent_id = agent_details->getAgentId();
|
||||
profile_id = agent_details->getProfileId();
|
||||
tenant_id = agent_details->getTenantId();
|
||||
auto maybe_fog_domain = agent_details->getFogDomain();
|
||||
if (maybe_fog_domain.ok()) {
|
||||
fog_address = maybe_fog_domain.unpack();
|
||||
} else {
|
||||
fog_address = "None";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
serialize(cereal::JSONOutputArchive &archive)
|
||||
{
|
||||
recoverFields();
|
||||
archive(cereal::make_nvp("Last update attempt", last_update_attempt));
|
||||
archive(cereal::make_nvp("Last update status", last_update_status));
|
||||
archive(cereal::make_nvp("Last update", last_update_time));
|
||||
archive(cereal::make_nvp("Last manifest update", last_manifest_update));
|
||||
archive(cereal::make_nvp("Policy version", policy_version));
|
||||
archive(cereal::make_nvp("Last policy update", last_policy_update));
|
||||
archive(cereal::make_nvp("Last settings update", last_settings_update));
|
||||
archive(cereal::make_nvp("Upgrade mode", upgrade_mode));
|
||||
archive(cereal::make_nvp("Fog address", fog_address));
|
||||
archive(cereal::make_nvp("Registration status", registration_status));
|
||||
archive(cereal::make_nvp("Registration details", registration_details));
|
||||
archive(cereal::make_nvp("Agent ID", agent_id));
|
||||
archive(cereal::make_nvp("Profile ID", profile_id));
|
||||
archive(cereal::make_nvp("Tenant ID", tenant_id));
|
||||
archive(cereal::make_nvp("Manifest status", manifest_status));
|
||||
archive(cereal::make_nvp("Service policy", service_policies));
|
||||
archive(cereal::make_nvp("Service settings", service_settings));
|
||||
}
|
||||
|
||||
void
|
||||
serialize(cereal::JSONInputArchive &archive)
|
||||
{
|
||||
archive(cereal::make_nvp("Last update attempt", last_update_attempt));
|
||||
archive(cereal::make_nvp("Last update status", last_update_status));
|
||||
archive(cereal::make_nvp("Last update", last_update_time));
|
||||
archive(cereal::make_nvp("Last manifest update", last_manifest_update));
|
||||
try {
|
||||
archive(cereal::make_nvp("Policy version", policy_version));
|
||||
} catch (...) {
|
||||
archive.setNextName(nullptr);
|
||||
}
|
||||
|
||||
archive(cereal::make_nvp("Last policy update", last_policy_update));
|
||||
archive(cereal::make_nvp("Last settings update", last_settings_update));
|
||||
|
||||
// Optional param (upgrade - new parameter)
|
||||
bool is_upgrade_mode = false;
|
||||
try {
|
||||
archive(cereal::make_nvp("Upgrade mode", upgrade_mode));
|
||||
is_upgrade_mode = true;
|
||||
} catch (...) {
|
||||
archive.setNextName(nullptr);
|
||||
}
|
||||
|
||||
if (!is_upgrade_mode) {
|
||||
try {
|
||||
archive(cereal::make_nvp("Update mode", upgrade_mode));
|
||||
} catch (...) {
|
||||
archive.setNextName(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
archive(cereal::make_nvp("Fog address", fog_address));
|
||||
archive(cereal::make_nvp("Registration status", registration_status));
|
||||
archive(cereal::make_nvp("Registration details", registration_details));
|
||||
archive(cereal::make_nvp("Agent ID", agent_id));
|
||||
archive(cereal::make_nvp("Profile ID", profile_id));
|
||||
archive(cereal::make_nvp("Tenant ID", tenant_id));
|
||||
archive(cereal::make_nvp("Manifest status", manifest_status));
|
||||
archive(cereal::make_nvp("Service policy", service_policies));
|
||||
archive(cereal::make_nvp("Service settings", service_settings));
|
||||
}
|
||||
|
||||
private:
|
||||
string last_update_time;
|
||||
string last_update_status;
|
||||
string last_update_attempt;
|
||||
string last_manifest_update;
|
||||
string policy_version;
|
||||
string last_policy_update;
|
||||
string last_settings_update;
|
||||
string upgrade_mode;
|
||||
string fog_address;
|
||||
string registration_status;
|
||||
string manifest_status;
|
||||
string manifest_error;
|
||||
string agent_id;
|
||||
string profile_id;
|
||||
string tenant_id;
|
||||
RegistrationDetails registration_details;
|
||||
map<string, string> service_policies;
|
||||
map<string, string> service_settings;
|
||||
};
|
||||
|
||||
class OrchestrationStatus::Impl : Singleton::Provide<I_OrchestrationStatus>::From<OrchestrationStatus>
|
||||
{
|
||||
public:
|
||||
void
|
||||
writeStatusToFile()
|
||||
{
|
||||
auto orchestrations_status_path = getConfigurationWithDefault<string>(
|
||||
filesystem_prefix + "/conf/orchestrations_status.json",
|
||||
"orchestration",
|
||||
"Orchestration status path"
|
||||
);
|
||||
auto write_result =
|
||||
orchestration_tools->objectToJsonFile<Status>(status, orchestrations_status_path);
|
||||
if (!write_result) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to write Orchestration status. File: " << orchestrations_status_path;
|
||||
}
|
||||
dbgTrace(D_ORCHESTRATOR) << "Orchestration status file has been updated. File: " << orchestrations_status_path;
|
||||
}
|
||||
|
||||
void
|
||||
recoverFields() override
|
||||
{
|
||||
status.recoverFields();
|
||||
}
|
||||
|
||||
void
|
||||
setServiceConfiguration(
|
||||
const string &service_name,
|
||||
const string &path,
|
||||
const OrchestrationStatusConfigType &configuration_file_type
|
||||
)
|
||||
{
|
||||
if (shouldPolicyStatusBeIgnored(service_name, path)) return;
|
||||
|
||||
switch (configuration_file_type) {
|
||||
case OrchestrationStatusConfigType::POLICY:
|
||||
status.insertServicePolicy(service_name, path);
|
||||
return;
|
||||
case OrchestrationStatusConfigType::SETTINGS:
|
||||
status.insertServiceSetting(service_name, path);
|
||||
return;
|
||||
case OrchestrationStatusConfigType::MANIFEST:
|
||||
dbgAssert(false) << "Manifest is not a service configuration file type";
|
||||
break;
|
||||
case OrchestrationStatusConfigType::DATA:
|
||||
return;
|
||||
case OrchestrationStatusConfigType::COUNT:
|
||||
break;
|
||||
}
|
||||
dbgAssert(false) << "Unknown configuration file type";
|
||||
}
|
||||
|
||||
void
|
||||
init()
|
||||
{
|
||||
time = Singleton::Consume<I_TimeGet>::by<OrchestrationStatus>();
|
||||
orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<OrchestrationStatus>();
|
||||
initValues();
|
||||
loadFromFile();
|
||||
|
||||
filesystem_prefix = getFilesystemPathConfig();
|
||||
dbgTrace(D_ORCHESTRATOR)
|
||||
<< "Initializing Orchestration status, file system path prefix: "
|
||||
<< filesystem_prefix;
|
||||
|
||||
map<string, string> service_policies_copy = status.getServicePolicies();
|
||||
for (const pair<string, string> &policy: service_policies_copy) {
|
||||
setServiceConfiguration(policy.first, policy.second, OrchestrationStatusConfigType::POLICY);
|
||||
}
|
||||
|
||||
auto mainloop = Singleton::Consume<I_MainLoop>::by<OrchestrationStatus>();
|
||||
mainloop->addRecurringRoutine(
|
||||
I_MainLoop::RoutineType::Timer,
|
||||
seconds(5),
|
||||
[this] ()
|
||||
{
|
||||
dbgTrace(D_ORCHESTRATOR) << "Write Orchestration status file <co-routine>";
|
||||
writeStatusToFile();
|
||||
},
|
||||
"Write Orchestration status file"
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
void initValues();
|
||||
bool shouldPolicyStatusBeIgnored(const string &service_name, const string &path);
|
||||
|
||||
void
|
||||
loadFromFile()
|
||||
{
|
||||
auto orchestrations_status_path = getConfigurationWithDefault<string>(
|
||||
filesystem_prefix + "/conf/orchestrations_status.json",
|
||||
"orchestration",
|
||||
"Orchestration status path"
|
||||
);
|
||||
Maybe<Status> maybe_status_file =
|
||||
orchestration_tools->jsonFileToObject<Status>(orchestrations_status_path);
|
||||
if (!maybe_status_file.ok()) {
|
||||
dbgTrace(D_ORCHESTRATOR)
|
||||
<< "Failed to load Orchestration status, start with clear status."
|
||||
<< " Error: " << maybe_status_file.getErr();
|
||||
return;
|
||||
}
|
||||
|
||||
status = maybe_status_file.unpack();
|
||||
|
||||
dbgInfo(D_ORCHESTRATOR) << "Orchestration status loaded from file." << " File: " << orchestrations_status_path;
|
||||
}
|
||||
|
||||
const string & getLastUpdateAttempt() const override { return status.getLastUpdateAttempt(); }
|
||||
const string & getUpdateStatus() const override { return status.getUpdateStatus(); }
|
||||
const string & getUpdateTime() const override { return status.getUpdateTime(); }
|
||||
const string & getLastManifestUpdate() const override { return status.getLastManifestUpdate(); }
|
||||
const string & getPolicyVersion() const override { return status.getPolicyVersion(); }
|
||||
const string & getLastPolicyUpdate() const override { return status.getLastPolicyUpdate(); }
|
||||
const string & getLastSettingsUpdate() const override { return status.getLastSettingsUpdate(); }
|
||||
const string & getUpgradeMode() const override { return status.getUpgradeMode(); }
|
||||
const string & getFogAddress() const override { return status.getFogAddress(); }
|
||||
const string & getRegistrationStatus() const override { return status.getRegistrationStatus(); }
|
||||
const string & getAgentId() const override { return status.getAgentId(); }
|
||||
const string & getProfileId() const override { return status.getProfileId(); }
|
||||
const string & getTenantId() const override { return status.getTenantId(); }
|
||||
const string & getManifestStatus() const override { return status.getManifestStatus(); }
|
||||
const string & getManifestError() const override { return status.getManifestError(); }
|
||||
const string getRegistrationDetails() const override { return status.getRegistrationDetails().toString(); }
|
||||
const map<string, string> & getServicePolicies() const override { return status.getServicePolicies(); }
|
||||
const map<string, string> & getServiceSettings() const override { return status.getServiceSettings(); }
|
||||
|
||||
void
|
||||
setIsConfigurationUpdated(EnumArray<OrchestrationStatusConfigType, bool> config_types) override
|
||||
{
|
||||
status.setIsConfigurationUpdated(config_types, time->getLocalTimeStr());
|
||||
}
|
||||
|
||||
void
|
||||
setPolicyVersion(const string &_policy_version) override
|
||||
{
|
||||
status.setPolicyVersion(_policy_version);
|
||||
}
|
||||
|
||||
void
|
||||
setRegistrationStatus(const string &_reg_status) override
|
||||
{
|
||||
status.setRegistrationStatus(_reg_status);
|
||||
}
|
||||
|
||||
void
|
||||
setUpgradeMode(const string &_upgrade_mode) override
|
||||
{
|
||||
status.setUpgradeMode(_upgrade_mode);
|
||||
}
|
||||
|
||||
void
|
||||
setAgentType(const string &_agent_type) override
|
||||
{
|
||||
status.setAgentType(_agent_type);
|
||||
}
|
||||
|
||||
void
|
||||
setAgentDetails(
|
||||
const string &_agent_id,
|
||||
const string &_profile_id,
|
||||
const string &_tenant_id) override
|
||||
{
|
||||
status.setAgentDetails(_agent_id, _profile_id, _tenant_id);
|
||||
}
|
||||
|
||||
void
|
||||
setLastUpdateAttempt() override
|
||||
{
|
||||
status.setLastUpdateAttempt(time->getLocalTimeStr());
|
||||
}
|
||||
|
||||
void
|
||||
setFogAddress(const string &_fog_address) override
|
||||
{
|
||||
status.setFogAddress(_fog_address);
|
||||
}
|
||||
|
||||
void
|
||||
setFieldStatus(
|
||||
const OrchestrationStatusFieldType &field_type_status,
|
||||
const OrchestrationStatusResult &status_result,
|
||||
const string &failure_reason) override
|
||||
{
|
||||
string field_value = status_string_map.at(status_result) + " " + failure_reason;
|
||||
switch (field_type_status) {
|
||||
case OrchestrationStatusFieldType::REGISTRATION:
|
||||
status.setRegistrationStatus(field_value);
|
||||
return;
|
||||
case OrchestrationStatusFieldType::MANIFEST:
|
||||
status.setManifestStatus(field_value);
|
||||
status.setManifestError(failure_reason);
|
||||
return;
|
||||
case OrchestrationStatusFieldType::LAST_UPDATE:
|
||||
if (status_result == OrchestrationStatusResult::SUCCESS) {
|
||||
status.setLastUpdateTime(time->getLocalTimeStr());
|
||||
}
|
||||
if (status.getUpdateStatus() != field_value) {
|
||||
writeStatusToFile();
|
||||
}
|
||||
status.setLastUpdateStatus(field_value);
|
||||
return;
|
||||
case OrchestrationStatusFieldType::COUNT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setRegistrationDetails(
|
||||
const string &name,
|
||||
const string &type,
|
||||
const string &platform,
|
||||
const string &arch) override
|
||||
{
|
||||
status.setRegistrationDetails(name, type, platform, arch);
|
||||
}
|
||||
|
||||
OrchestrationStatus::Impl & operator=(OrchestrationStatus::Impl &&from) = default;
|
||||
OrchestrationStatus::Impl & operator=(const OrchestrationStatus::Impl &from) = default;
|
||||
|
||||
const map<OrchestrationStatusResult, string> status_string_map = {
|
||||
{ OrchestrationStatusResult::SUCCESS, "Succeeded" },
|
||||
{ OrchestrationStatusResult::FAILED, "Failed. Reason:" }
|
||||
};
|
||||
|
||||
Status status;
|
||||
I_TimeGet *time;
|
||||
I_OrchestrationTools *orchestration_tools;
|
||||
string filesystem_prefix;
|
||||
|
||||
};
|
||||
|
||||
void
|
||||
OrchestrationStatus::Impl::initValues()
|
||||
{
|
||||
status.initValues();
|
||||
}
|
||||
|
||||
bool
|
||||
OrchestrationStatus::Impl::shouldPolicyStatusBeIgnored(
|
||||
const string &service_name,
|
||||
const string &path)
|
||||
{
|
||||
vector<string> default_status_ingored_policies = {
|
||||
"rules",
|
||||
"zones",
|
||||
"triggers",
|
||||
"parameters",
|
||||
"orchestration",
|
||||
"webUserResponse",
|
||||
"kubernetescalico",
|
||||
"activeContextConfig"
|
||||
};
|
||||
|
||||
auto status_ingored_policies = getSettingWithDefault<vector<string>>(
|
||||
default_status_ingored_policies,
|
||||
"orchestration",
|
||||
"Orchestration status ignored policies"
|
||||
);
|
||||
|
||||
auto config_content = orchestration_tools->readFile(path);
|
||||
|
||||
if (!config_content.ok() || config_content.unpack().empty()) {
|
||||
dbgDebug(D_ORCHESTRATOR) << "Can not read the policy for " << service_name;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto find_exist_iterator = status.getServicePolicies().find(service_name);
|
||||
auto find_ignored_iterator = find(status_ingored_policies.begin(), status_ingored_policies.end(), service_name);
|
||||
|
||||
if (config_content.unpack() == "{}") {
|
||||
dbgDebug(D_ORCHESTRATOR) << "Skipping status print for an empty policy file. Policy name: " << service_name;
|
||||
if (find_exist_iterator != status.getServicePolicies().end()) {
|
||||
status.eraseServicePolicy(service_name);
|
||||
}
|
||||
return true;
|
||||
} else if (find_ignored_iterator != status_ingored_policies.end()) {
|
||||
dbgDebug(D_ORCHESTRATOR)
|
||||
<< "Skipping status print for the policy from a list of ignored policies. Policy name: "
|
||||
<< service_name;
|
||||
if (find_exist_iterator != status.getServicePolicies().end()) {
|
||||
status.eraseServicePolicy(service_name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
OrchestrationStatus::init() { pimpl->init(); }
|
||||
|
||||
OrchestrationStatus::OrchestrationStatus() : Component("OrchestrationStatus"), pimpl(make_unique<Impl>()) {}
|
||||
|
||||
OrchestrationStatus::~OrchestrationStatus() {}
|
||||
|
||||
SASAL_END
|
133
components/security_apps/orchestration/modules/package.cc
Executable file
133
components/security_apps/orchestration/modules/package.cc
Executable file
@@ -0,0 +1,133 @@
|
||||
// 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 "package.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "sasal.h"
|
||||
|
||||
SASAL_START // Orchestration - Modules
|
||||
|
||||
using namespace std;
|
||||
using namespace cereal;
|
||||
|
||||
const map<string, Package::ChecksumTypes> checksumMap = {
|
||||
{ "sha1sum", Package::ChecksumTypes::SHA1 },
|
||||
{ "sha256sum", Package::ChecksumTypes::SHA256 },
|
||||
{ "sha512sum", Package::ChecksumTypes::SHA512 },
|
||||
{ "md5sum", Package::ChecksumTypes::MD5 },
|
||||
};
|
||||
|
||||
const map<string, Package::PackageType> packageTypeMap = {
|
||||
{ "service", Package::PackageType::Service },
|
||||
{ "shared objects", Package::PackageType::SharedObject },
|
||||
};
|
||||
|
||||
bool
|
||||
Package::operator==(const Package &other) const
|
||||
{
|
||||
return checksum_type == other.getChecksumType() && checksum_value == other.getChecksum();
|
||||
}
|
||||
|
||||
bool
|
||||
Package::operator!=(const Package &other) const
|
||||
{
|
||||
return !((*this) == other);
|
||||
}
|
||||
|
||||
void
|
||||
Package::serialize(JSONOutputArchive & out_archive) const
|
||||
{
|
||||
string type = mapTypeToString<PackageType>(package_type, packageTypeMap);
|
||||
string checksum_type_as_string = mapTypeToString<ChecksumTypes>(checksum_type, checksumMap);
|
||||
out_archive(make_nvp("download-path", download_path));
|
||||
out_archive(make_nvp("relative-path", relative_path));
|
||||
out_archive(make_nvp("version", version));
|
||||
out_archive(make_nvp("name", name));
|
||||
out_archive(make_nvp("checksum-type", checksum_type_as_string));
|
||||
out_archive(make_nvp("checksum", checksum_value));
|
||||
out_archive(make_nvp("package-type", type));
|
||||
|
||||
if (require_packages.size() > 0) {
|
||||
out_archive(make_nvp("require", require_packages));
|
||||
}
|
||||
|
||||
if (!installable.ok()) {
|
||||
out_archive(make_nvp("status", installable.ok()));
|
||||
out_archive(make_nvp("message", installable.getErr()));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Package::serialize(JSONInputArchive & in_archive)
|
||||
{
|
||||
string type;
|
||||
string checksum_type_as_string;
|
||||
in_archive(make_nvp("download-path", download_path));
|
||||
in_archive(make_nvp("version", version));
|
||||
in_archive(make_nvp("name", name));
|
||||
in_archive(make_nvp("checksum-type", checksum_type_as_string));
|
||||
in_archive(make_nvp("checksum", checksum_value));
|
||||
in_archive(make_nvp("package-type", type));
|
||||
|
||||
try {
|
||||
in_archive(make_nvp("relative-path", relative_path));
|
||||
} catch (...) {
|
||||
in_archive.setNextName(nullptr);
|
||||
}
|
||||
|
||||
try {
|
||||
in_archive(make_nvp("require", require_packages));
|
||||
} catch (...) {
|
||||
in_archive.setNextName(nullptr);
|
||||
}
|
||||
|
||||
bool is_installable = true;
|
||||
try {
|
||||
in_archive(make_nvp("status", is_installable));
|
||||
} catch (...) {
|
||||
in_archive.setNextName(nullptr);
|
||||
}
|
||||
|
||||
if (!is_installable) {
|
||||
string error_message;
|
||||
try {
|
||||
in_archive(make_nvp("message", error_message));
|
||||
} catch (...) {
|
||||
in_archive.setNextName(nullptr);
|
||||
}
|
||||
installable = genError(error_message);
|
||||
}
|
||||
|
||||
for (auto &character : name) {
|
||||
// Name Validation: should include only: decimal digit / letter / '.' / '_' / '-'
|
||||
if (!isalnum(character) && character != '.' && character != '_' && character != '-') {
|
||||
throw Exception(name + " is invalid package name");
|
||||
}
|
||||
}
|
||||
|
||||
auto checksum_type_value = checksumMap.find(checksum_type_as_string);
|
||||
if (checksum_type_value == checksumMap.end()) {
|
||||
throw Exception(checksum_type_as_string + " isn't a valid checksum type at " + name);
|
||||
}
|
||||
checksum_type = checksum_type_value->second;
|
||||
|
||||
auto package_type_value = packageTypeMap.find(type);
|
||||
if (package_type_value == packageTypeMap.end()) {
|
||||
throw Exception(checksum_type_as_string + " isn't a valid package type at " + name);
|
||||
}
|
||||
package_type = package_type_value->second;
|
||||
}
|
||||
|
||||
SASAL_END
|
149
components/security_apps/orchestration/modules/url_parser.cc
Executable file
149
components/security_apps/orchestration/modules/url_parser.cc
Executable file
@@ -0,0 +1,149 @@
|
||||
// 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 "url_parser.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "singleton.h"
|
||||
#include "common.h"
|
||||
#include "maybe_res.h"
|
||||
#include "sasal.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
SASAL_START // Orchestration - Modules
|
||||
|
||||
USE_DEBUG_FLAG(D_ORCHESTRATOR);
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const URLParser &url)
|
||||
{
|
||||
return os << url.toString();
|
||||
}
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const URLProtocol &protocol)
|
||||
{
|
||||
switch(protocol) {
|
||||
case URLProtocol::HTTP: {
|
||||
return os << "http://";
|
||||
}
|
||||
case URLProtocol::HTTPS: {
|
||||
return os << "https://";
|
||||
}
|
||||
case URLProtocol::LOCAL_FILE: {
|
||||
return os << "file://";
|
||||
}
|
||||
default: {
|
||||
dbgAssert(false) << "Unsupported protocol " << static_cast<unsigned int>(protocol);
|
||||
return os;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
URLParser::URLParser(const string &url)
|
||||
{
|
||||
parseURL(url);
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
URLParser::getBaseURL() const
|
||||
{
|
||||
if (base_url.empty()) return genError("Error: URL not found");
|
||||
return base_url;
|
||||
}
|
||||
|
||||
void
|
||||
URLParser::parseURL(const string &url)
|
||||
{
|
||||
string url_builder;
|
||||
protocol = parseProtocol(url);
|
||||
switch(protocol) {
|
||||
case URLProtocol::HTTP: {
|
||||
dbgDebug(D_ORCHESTRATOR) << "Protocol of " << url << " is HTTP";
|
||||
port = "80";
|
||||
over_ssl = false;
|
||||
url_builder = url.substr(7);
|
||||
break;
|
||||
}
|
||||
case URLProtocol::HTTPS: {
|
||||
dbgDebug(D_ORCHESTRATOR) << "Protocol of " << url << " is HTTPS";
|
||||
if (url.find("https://") != string::npos) {
|
||||
url_builder = url.substr(8);
|
||||
} else {
|
||||
url_builder = url;
|
||||
}
|
||||
port = "443";
|
||||
over_ssl = true;
|
||||
break;
|
||||
}
|
||||
case URLProtocol::LOCAL_FILE: {
|
||||
dbgDebug(D_ORCHESTRATOR) << "Protocol of " << url << " is local file.";
|
||||
base_url = url.substr(7);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
dbgAssert(false) << "URL protocol is not supported. Protocol: " << static_cast<unsigned int>(protocol);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
size_t link_extension_position = url_builder.find_first_of("/");
|
||||
if (link_extension_position != string::npos) {
|
||||
query = url_builder.substr(link_extension_position);
|
||||
url_builder = url_builder.substr(0, link_extension_position);
|
||||
}
|
||||
|
||||
size_t port_position = url_builder.find_last_of(":");
|
||||
string link = url_builder;
|
||||
if (port_position != string::npos) {
|
||||
link = url_builder.substr(0, port_position);
|
||||
port = url_builder.substr(port_position + 1);
|
||||
}
|
||||
|
||||
if (!link.empty()) base_url = link;
|
||||
if (!query.empty() && query.back() == '/') query.pop_back();
|
||||
}
|
||||
|
||||
URLProtocol
|
||||
URLParser::parseProtocol(const string &url) const
|
||||
{
|
||||
if (url.find("http://") != string::npos) {
|
||||
return URLProtocol::HTTP;
|
||||
} else if (url.find("https://") != string::npos) {
|
||||
return URLProtocol::HTTPS;
|
||||
} else if (url.find("file://") != string::npos){
|
||||
return URLProtocol::LOCAL_FILE;
|
||||
}
|
||||
|
||||
dbgWarning(D_ORCHESTRATOR)
|
||||
<< "No supported protocol in URL, HTTPS default value is used. URL: " << url;
|
||||
return URLProtocol::HTTPS;
|
||||
}
|
||||
|
||||
void
|
||||
URLParser::setQuery(const string &new_query)
|
||||
{
|
||||
query = new_query;
|
||||
}
|
||||
|
||||
string
|
||||
URLParser::toString() const
|
||||
{
|
||||
stringstream s_build;
|
||||
s_build << protocol << base_url << query << ":" << port;
|
||||
return s_build.str();
|
||||
}
|
||||
|
||||
SASAL_END
|
Reference in New Issue
Block a user