May 27 update

This commit is contained in:
Ned Wright
2024-05-27 08:45:25 +00:00
parent 253ca70de6
commit fdc148aa9b
39 changed files with 1140 additions and 359 deletions

View File

@@ -45,6 +45,7 @@ public:
bool isVersionAboveR8110() override;
bool isReverseProxy() override;
bool isCloudStorageEnabled() override;
Maybe<tuple<string, string, string>> readCloudMetadata() override;
Maybe<tuple<string, string, string>> parseNginxMetadata() override;
#if defined(gaia) || defined(smb)
bool compareCheckpointVersion(int cp_version, std::function<bool(int, int)> compare_operator) const override;
@@ -188,17 +189,16 @@ DetailsResolver::Impl::getCheckpointVersion() const
{
#ifdef gaia
static const string cmd =
"echo $CPDIR | awk -F'-' '{print $NF}' | cut -c 2- |"
" awk -F'.' '{ if( NF == 1 ) {print $1\"00\"} else {print $1$2} }'";
"echo $CPDIR | awk '{sub(/.*-R/,\"\"); sub(/\\/.*/,\"\")}/^[0-9]*$/{$0=$0\".00\"}{sub(/\\./, \"\"); print}'";
#else // smb
static const string cmd = "sqlcmd 'select major,minor from cpver' |"
"awk '{if ($1 == \"major\") v += (substr($3,2) * 100);"
" if ($1 == \"minor\") v += $3; } END { print v}'";
#endif // gaia
auto version_out = DetailsResolvingHanlder::getCommandOutput(cmd);
int cp_version = 0;
if (version_out.ok()) {
dbgTrace(D_ORCHESTRATOR) << "Identified version " << version_out.unpack();
stringstream version_stream(version_out.unpack());
version_stream >> cp_version;
}
@@ -300,6 +300,58 @@ DetailsResolver::Impl::parseNginxMetadata()
return make_tuple(config_opt, cc_opt, nginx_version);
}
Maybe<tuple<string, string, string>>
DetailsResolver::Impl::readCloudMetadata()
{
auto env_read_cloud_metadata = []() -> Maybe<tuple<string, string, string>> {
string account_id = getenv("CLOUD_ACCOUNT_ID") ? getenv("CLOUD_ACCOUNT_ID") : "";
string vpc_id = getenv("CLOUD_VPC_ID") ? getenv("CLOUD_VPC_ID") : "";
string instance_id = getenv("CLOUD_INSTANCE_ID") ? getenv("CLOUD_INSTANCE_ID") : "";
if (account_id.empty() || vpc_id.empty() || instance_id.empty()) {
return genError("Could not read cloud metadata");
}
return make_tuple(account_id, vpc_id, instance_id);
};
auto cloud_metadata = env_read_cloud_metadata();
if (!cloud_metadata.ok()) {
const string cmd = getFilesystemPathConfig() + "/scripts/get-cloud-metadata.sh";
dbgTrace(D_ORCHESTRATOR) << cloud_metadata.getErr() << ", trying to fetch it via cmd: " << cmd;
auto result = DetailsResolvingHanlder::getCommandOutput(cmd);
if (result.ok()) {
istringstream iss(result.unpack());
string line;
while (getline(iss, line)) {
size_t pos = line.find('=');
if (pos != string::npos) {
string key = line.substr(0, pos);
string value = line.substr(pos + 1);
if (!key.empty() && !value.empty()) setenv(key.c_str(), value.c_str(), 1);
}
}
cloud_metadata = env_read_cloud_metadata();
} else {
dbgWarning(D_ORCHESTRATOR) << "Could not fetch cloud metadata from cmd: " << result.getErr();
}
}
if (!cloud_metadata.ok()) {
dbgWarning(D_ORCHESTRATOR) << cloud_metadata.getErr();
return genError("Failed to fetch cloud metadata");
}
dbgTrace(D_ORCHESTRATOR)
<< "Successfully fetched cloud metadata: "
<< ::get<0>(cloud_metadata.unpack()) << ", "
<< ::get<1>(cloud_metadata.unpack()) << ", "
<< ::get<2>(cloud_metadata.unpack());
return cloud_metadata.unpack();
}
DetailsResolver::DetailsResolver() : Component("DetailsResolver"), pimpl(make_unique<Impl>()) {}
DetailsResolver::~DetailsResolver() {}

View File

@@ -15,7 +15,9 @@
#define __CHECKPOINT_PRODUCT_HANDLERS_H__
#include <algorithm>
#include <regex>
#include <boost/regex.hpp>
#include <boost/algorithm/string.hpp>
#if defined(gaia)
@@ -63,6 +65,16 @@ checkPepIdaIdnStatus(const string &command_output)
return genError("Current host does not have PEP control IDA IDN enabled");
}
Maybe<string>
checkAgentIntelligence(const string &command_output)
{
if (command_output.find("is registered") != string::npos) {
return string("true");
}
return genError("Current host does not have agent intelligence installed");
}
Maybe<string>
getIDAGaiaPackages(const string &command_output)
{
@@ -324,6 +336,34 @@ getSmbGWIPSecVPNBlade(const string &command_output)
{
return getSmbBlade(command_output, "IPSec VPN Blade was not found");
}
Maybe<string>
extractManagements(const string &command_output)
{
size_t start_pos = command_output.find(":masters(");
if (start_pos == string::npos) {
return genError("Starting pattern \":masters(\" not found.");
}
size_t end_pos = command_output.find("))):", start_pos);
if (end_pos == string::npos) {
return genError("Ending pattern \"))):\" not found.");
}
string input_string = command_output.substr(start_pos, end_pos - start_pos + 3);
string json_output = "[";
regex pattern("\\(ReferenceObject\\:Uid\\(\"\\{([\\w-]+)\\}\"\\)\\:Name\\(([^\\)]+)\\)\\:Table\\(([^\\)]+)\\)\\)");
smatch matches;
auto words_begin = sregex_iterator(input_string.begin(), input_string.end(), pattern);
auto words_end = sregex_iterator();
for (sregex_iterator i = words_begin; i != words_end; ++i) {
const smatch& match = *i;
string uid = boost::algorithm::to_lower_copy(match[1].str());
string name = match[2].str();
if (json_output.back() != '[') json_output += ",";
json_output += "{\"Uid\":\"" + uid + "\",\"Name\":\"" + name + "\"}";
}
json_output += "]";
return json_output;
}
#endif // gaia || smb
#if defined(gaia)

View File

@@ -43,8 +43,8 @@ SHELL_PRE_CMD("gunzip local.cfg", "gunzip -c $FWDIR/state/local/FW1/local.cfg.gz
#if defined(gaia) || defined(smb)
SHELL_CMD_HANDLER("cpProductIntegrationMgmtObjectType", "cpprod_util CPPROD_IsMgmtMachine", getMgmtObjType)
SHELL_CMD_HANDLER("prerequisitesForHorizonTelemetry",
"[ -f /var/log/nano_agent/cp-nano-horizon-telemetry-prerequisites.log ] "
"&& head -1 /var/log/nano_agent/cp-nano-horizon-telemetry-prerequisites.log || echo ''",
"FS_PATH=<FILESYSTEM-PREFIX>; [ -f ${FS_PATH}/cp-nano-horizon-telemetry-prerequisites.log ] "
"&& head -1 ${FS_PATH}/cp-nano-horizon-telemetry-prerequisites.log || echo ''",
checkIsInstallHorizonTelemetrySucceeded)
SHELL_CMD_HANDLER("QUID", "[ -d /opt/CPquid ] "
"&& python3 /opt/CPquid/Quid_Api.py -i /opt/CPotelcol/quid_api/get_global_id.json | jq -r .message || echo ''",
@@ -99,6 +99,12 @@ SHELL_CMD_HANDLER(
SHELL_CMD_HANDLER("hasSAMLSupportedBlade", "enabled_blades", checkSAMLSupportedBlade)
SHELL_CMD_HANDLER("hasIDABlade", "enabled_blades", checkIDABlade)
SHELL_CMD_HANDLER("hasSAMLPortal", "mpclient status nac", checkSAMLPortal)
SHELL_CMD_HANDLER(
"hasAgentIntelligenceInstalled",
"<FILESYSTEM-PREFIX>/watchdog/cp-nano-watchdog "
"--status --service <FILESYSTEM-PREFIX>/agentIntelligence/cp-nano-agent-intelligence-service",
checkAgentIntelligence
)
SHELL_CMD_HANDLER("hasIdaIdnEnabled", "pep control IDN_nano_Srv_support status", checkPepIdaIdnStatus)
SHELL_CMD_HANDLER("requiredNanoServices", "ida_packages", getIDAGaiaPackages)
SHELL_CMD_HANDLER(
@@ -149,6 +155,12 @@ SHELL_CMD_HANDLER(
"| awk -F '[:()]' '/:masters/ {found=1; next} found && /:Name/ {print $3; exit}'",
getSMCBasedMgmtName
)
SHELL_CMD_HANDLER(
"managements",
"sed -n '/:masters (/,$p' $FWDIR/database/myself_objects.C |"
" sed -e ':a' -e 'N' -e '$!ba' -e 's/\\n//g' -e 's/\t//g' -e 's/ //g' | sed 's/))):.*/)))):/'",
extractManagements
)
#endif //gaia
#if defined(smb)
@@ -199,6 +211,13 @@ SHELL_CMD_HANDLER(
"| awk -F '[:()]' '/:masters/ {found=1; next} found && /:Name/ {print $3; exit}'",
getSMCBasedMgmtName
)
SHELL_CMD_HANDLER(
"managements",
"sed -n '/:masters (/,$p' /tmp/local.cfg |"
" sed -e ':a' -e 'N' -e '$!ba' -e 's/\\n//g' -e 's/\t//g' -e 's/ //g' | sed 's/))):.*/)))):/'",
extractManagements
)
#endif//smb
SHELL_CMD_OUTPUT("kernel_version", "uname -r")

View File

@@ -77,14 +77,22 @@ void
DetailsResolvingHanlder::Impl::init()
{
string actual_filesystem_prefix = getFilesystemPathConfig();
size_t place_holder_size = filesystem_place_holder.size();
for (auto &file_handler : file_content_handlers) {
string &path = file_handler.second.first;
size_t place_holder_size = filesystem_place_holder.size();
if (path.substr(0, place_holder_size) == filesystem_place_holder) {
path = actual_filesystem_prefix + path.substr(place_holder_size);
}
}
for (auto &cmd_handler_pair : shell_command_handlers) {
string &cmd_str = cmd_handler_pair.second.first;
size_t fs_pos = cmd_str.find(filesystem_place_holder);
if (fs_pos != string::npos) {
cmd_str.replace(fs_pos, place_holder_size, actual_filesystem_prefix);
}
}
}
map<string, string>

View File

@@ -246,7 +246,7 @@ private:
}
}
routine_id = i_mainloop->addFileRoutine(
I_MainLoop::RoutineType::RealTime,
I_MainLoop::RoutineType::System,
server_sock,
[this] () { handleConnection(); },
"Health check probe server",
@@ -344,7 +344,7 @@ private:
dbgDebug(D_HEALTH_CHECK) << "Successfully accepted client, client fd: " << new_client_socket;
open_connections_counter++;
auto curr_routine = i_mainloop->addOneTimeRoutine(
I_MainLoop::RoutineType::RealTime,
I_MainLoop::RoutineType::System,
[this] ()
{
auto curr_routine_id = i_mainloop->getCurrentRoutineId().unpack();

View File

@@ -111,12 +111,12 @@ TEST_F(HealthCheckerTest, clientConnection)
EXPECT_CALL(
mock_mainloop,
addFileRoutine(I_MainLoop::RoutineType::RealTime, _, _, _, true)
addFileRoutine(I_MainLoop::RoutineType::System, _, _, _, true)
).WillRepeatedly(DoAll(SaveArg<2>(&connection_handler_routine), Return(0)));
EXPECT_CALL(
mock_mainloop,
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Health check probe connection handler", true)
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, "Health check probe connection handler", true)
).WillOnce(DoAll(SaveArg<1>(&connection_handler_routine), Return(0)));
int socket = 1;
@@ -145,7 +145,7 @@ TEST_F(HealthCheckerTest, loadFromDynamicConfiguration)
EXPECT_CALL(
mock_mainloop,
addFileRoutine(I_MainLoop::RoutineType::RealTime, _, _, _, true)
addFileRoutine(I_MainLoop::RoutineType::System, _, _, _, true)
).WillRepeatedly(DoAll(SaveArg<2>(&connection_handler_routine), Return(0)));
health_checker.init();
@@ -183,7 +183,7 @@ TEST_F(HealthCheckerTest, connectionsLimit)
EXPECT_CALL(
mock_mainloop,
addFileRoutine(I_MainLoop::RoutineType::RealTime, _, _, _, true)
addFileRoutine(I_MainLoop::RoutineType::System, _, _, _, true)
).WillRepeatedly(DoAll(SaveArg<2>(&connection_handler_routine), Return(0)));
EXPECT_CALL(mock_mainloop, doesRoutineExist(_)).WillRepeatedly(Return(false));
@@ -218,12 +218,12 @@ TEST_F(HealthCheckerTest, disablingAfterEnabled)
EXPECT_CALL(
mock_mainloop,
addFileRoutine(I_MainLoop::RoutineType::RealTime, _, _, _, true)
addFileRoutine(I_MainLoop::RoutineType::System, _, _, _, true)
).WillRepeatedly(DoAll(SaveArg<2>(&connection_handler_routine), Return(0)));
EXPECT_CALL(
mock_mainloop,
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Health check probe connection handler", true)
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, "Health check probe connection handler", true)
).WillOnce(DoAll(SaveArg<1>(&connection_handler_routine), Return(0)));
int socket = 1;
@@ -273,12 +273,12 @@ TEST_F(HealthCheckerTest, changePortIpConfig)
EXPECT_CALL(
mock_mainloop,
addFileRoutine(I_MainLoop::RoutineType::RealTime, _, _, _, true)
addFileRoutine(I_MainLoop::RoutineType::System, _, _, _, true)
).WillRepeatedly(DoAll(SaveArg<2>(&connection_handler_routine), Return(0)));
EXPECT_CALL(
mock_mainloop,
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Health check probe connection handler", true)
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, "Health check probe connection handler", true)
).WillOnce(DoAll(SaveArg<1>(&connection_handler_routine), Return(0)));
int socket = 1;
@@ -321,12 +321,12 @@ TEST_F(HealthCheckerTest, FailedHealthCheck)
EXPECT_CALL(
mock_mainloop,
addFileRoutine(I_MainLoop::RoutineType::RealTime, _, _, _, true)
addFileRoutine(I_MainLoop::RoutineType::System, _, _, _, true)
).WillRepeatedly(DoAll(SaveArg<2>(&connection_handler_routine), Return(0)));
EXPECT_CALL(
mock_mainloop,
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Health check probe connection handler", true)
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, "Health check probe connection handler", true)
).WillOnce(DoAll(SaveArg<1>(&connection_handler_routine), Return(0)));
int socket = 1;

View File

@@ -42,6 +42,7 @@ public:
MOCK_METHOD0(getResolvedDetails, std::map<std::string, std::string>());
MOCK_METHOD0(isVersionAboveR8110, bool());
MOCK_METHOD0(parseNginxMetadata, Maybe<std::tuple<std::string, std::string, std::string>>());
MOCK_METHOD0(readCloudMetadata, Maybe<std::tuple<std::string, std::string, std::string>>());
};
#endif // __MOCK_DETAILS_RESOLVER_H__

View File

@@ -203,7 +203,7 @@ public:
loadFogAddress();
Singleton::Consume<I_MainLoop>::by<OrchestrationComp>()->addOneTimeRoutine(
I_MainLoop::RoutineType::RealTime,
I_MainLoop::RoutineType::System,
[this] () { run(); },
"Orchestration runner",
true
@@ -1290,6 +1290,21 @@ private:
}
}
void
reportCloudMetadata(AgentDataReport &report)
{
I_DetailsResolver *i_details_resolver = Singleton::Consume<I_DetailsResolver>::by<OrchestrationComp>();
auto cloud_metadata = i_details_resolver->readCloudMetadata();
if (!cloud_metadata.ok()) {
dbgDebug(D_ORCHESTRATOR) << cloud_metadata.getErr();
return;
}
report << make_pair("cloudAccountId", ::get<0>(cloud_metadata.unpack()));
report << make_pair("cloudVpcId", ::get<1>(cloud_metadata.unpack()));
report << make_pair("cloudInstanceId", ::get<2>(cloud_metadata.unpack()));
}
void
reportAgentDetailsMetaData()
{
@@ -1335,6 +1350,8 @@ private:
agent_data_report << AgentReportFieldWithLabel("cloud_storage_service", "false");
}
reportCloudMetadata(agent_data_report);
if (i_details_resolver->isKernelVersion3OrHigher()) {
agent_data_report << AgentReportFieldWithLabel("isKernelVersion3OrHigher", "true");
}

View File

@@ -88,7 +88,7 @@ public:
// This Holding the Main Routine of the Orchestration.
EXPECT_CALL(
mock_ml,
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Orchestration runner", true)
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, "Orchestration runner", true)
).WillOnce(DoAll(SaveArg<1>(&routine), Return(1)));
EXPECT_CALL(mock_shell_cmd, getExecOutput("openssl version -d | cut -d\" \" -f2 | cut -d\"\\\"\" -f2", _, _))
@@ -143,6 +143,9 @@ public:
map<string, string> resolved_mgmt_details({{"kernel_version", "4.4.0-87-generic"}});
EXPECT_CALL(mock_details_resolver, getResolvedDetails()).WillRepeatedly(Return(resolved_mgmt_details));
EXPECT_CALL(mock_details_resolver, readCloudMetadata()).WillRepeatedly(
Return(Maybe<tuple<string, string, string>>(genError("No cloud metadata")))
);
}
void

View File

@@ -79,7 +79,7 @@ public:
EXPECT_CALL(mock_orchestration_tools, setClusterId());
EXPECT_CALL(
mock_ml,
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Orchestration runner", true)
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, "Orchestration runner", true)
).WillOnce(DoAll(SaveArg<1>(&routine), Return(1)));
EXPECT_CALL(
@@ -170,6 +170,9 @@ public:
map<string, string> resolved_mgmt_details({{"kernel_version", "4.4.0-87-generic"}});
EXPECT_CALL(mock_details_resolver, getResolvedDetails()).WillRepeatedly(Return(resolved_mgmt_details));
EXPECT_CALL(mock_details_resolver, readCloudMetadata()).WillRepeatedly(
Return(Maybe<tuple<string, string, string>>(genError("No cloud metadata")))
);
}
string
@@ -990,7 +993,7 @@ TEST_F(OrchestrationTest, loadOrchestrationPolicyFromBackup)
EXPECT_CALL(
mock_ml,
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Orchestration runner", true)
addOneTimeRoutine(I_MainLoop::RoutineType::System, _, "Orchestration runner", true)
);
EXPECT_CALL(

View File

@@ -179,6 +179,15 @@ FogAuthenticator::registerAgent(
dbgDebug(D_ORCHESTRATOR) << nginx_data.getErr();
}
auto cloud_metadata = details_resolver->readCloudMetadata();
if (cloud_metadata.ok()) {
request << make_pair("cloudAccountId", ::get<0>(cloud_metadata.unpack()));
request << make_pair("cloudVpcId", ::get<1>(cloud_metadata.unpack()));
request << make_pair("cloudInstanceId", ::get<2>(cloud_metadata.unpack()));
} else {
dbgDebug(D_ORCHESTRATOR) << cloud_metadata.getErr();
}
for (const pair<string, string> details : details_resolver->getResolvedDetails()) {
request << details;
}
@@ -450,9 +459,9 @@ getDeplymentType()
auto deplyment_type = Singleton::Consume<I_EnvDetails>::by<FogAuthenticator>()->getEnvType();
switch (deplyment_type) {
case EnvType::LINUX: return "Embedded";
case EnvType::DOCKER: return "Embedded";
case EnvType::DOCKER: return "Docker";
case EnvType::NON_CRD_K8S:
case EnvType::K8S: return "Embedded";
case EnvType::K8S: return "K8S";
case EnvType::COUNT: break;
}
@@ -579,7 +588,7 @@ FogAuthenticator::authenticateAgent()
auto mainloop = Singleton::Consume<I_MainLoop>::by<FogAuthenticator>();
if (!mainloop->doesRoutineExist(routine)) {
routine = mainloop->addOneTimeRoutine(
I_MainLoop::RoutineType::RealTime,
I_MainLoop::RoutineType::System,
[this, min_expiration_time] ()
{
uint expiration_time;