mirror of
https://github.com/openappsec/openappsec.git
synced 2025-06-28 16:41:02 +03:00
Merge pull request #122 from openappsec/Apr_14_2024-Dev
Apr 14 2024 dev
This commit is contained in:
commit
189c9209c9
@ -1136,7 +1136,8 @@ private:
|
||||
NginxAttachmentOpaque &opaque = i_transaction_table->getState<NginxAttachmentOpaque>();
|
||||
uuid = opaque.getSessionUUID();
|
||||
}
|
||||
web_response_data.uuid_size = uuid.size();
|
||||
web_response_data.uuid_size =
|
||||
string("Incident Id: ").length() + uuid.size();
|
||||
|
||||
if (web_trigger_conf.getDetailsLevel() == "Redirect") {
|
||||
web_response_data.response_data.redirect_data.redirect_location_size =
|
||||
|
@ -1,137 +0,0 @@
|
||||
// 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 "generic_rulebase/assets_config.h"
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "generic_rulebase/generic_rulebase_utils.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "ip_utilities.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
using namespace std;
|
||||
|
||||
void
|
||||
RuleAsset::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
archive_in(cereal::make_nvp("assetId", asset_id));
|
||||
archive_in(cereal::make_nvp("assetName", asset_name));
|
||||
archive_in(cereal::make_nvp("assetUrls", asset_urls));
|
||||
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Adding asset with UID: " << asset_id;
|
||||
}
|
||||
|
||||
void
|
||||
RuleAsset::AssetUrl::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
archive_in(cereal::make_nvp("protocol", protocol));
|
||||
transform(protocol.begin(), protocol.end(), protocol.begin(), [](unsigned char c) { return tolower(c); });
|
||||
|
||||
archive_in(cereal::make_nvp("ip", ip));
|
||||
archive_in(cereal::make_nvp("port", port));
|
||||
|
||||
int value;
|
||||
if (protocol == "*") {
|
||||
is_any_proto = true;
|
||||
} else {
|
||||
is_any_proto = false;
|
||||
try {
|
||||
value = 0;
|
||||
if(protocol == "udp") value = IPPROTO_UDP;
|
||||
if(protocol == "tcp") value = IPPROTO_TCP;
|
||||
if(protocol == "dccp") value = IPPROTO_DCCP;
|
||||
if(protocol == "sctp") value = IPPROTO_SCTP;
|
||||
if(protocol == "icmp") value = IPPROTO_ICMP;
|
||||
if(protocol == "icmpv6") value = IPPROTO_ICMP;
|
||||
|
||||
if (value > static_cast<int>(UINT8_MAX) || value < 0) {
|
||||
dbgWarning(D_RULEBASE_CONFIG)
|
||||
<< "provided value is not a legal IP protocol number. Value: "
|
||||
<< protocol;
|
||||
} else {
|
||||
parsed_proto = value;
|
||||
}
|
||||
} catch (...) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "provided value is not a legal IP protocol. Value: " << protocol;
|
||||
}
|
||||
}
|
||||
|
||||
if (port == "*") {
|
||||
is_any_port = true;
|
||||
} else {
|
||||
is_any_port = false;
|
||||
try {
|
||||
value = stoi(port);
|
||||
if (value > static_cast<int>(UINT16_MAX) || value < 0) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "provided value is not a legal port number. Value: " << port;
|
||||
} else {
|
||||
parsed_port = value;
|
||||
}
|
||||
} catch (...) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "provided value is not a legal port. Value: " << port;
|
||||
}
|
||||
}
|
||||
|
||||
if (ip == "*") {
|
||||
is_any_ip = true;
|
||||
} else {
|
||||
is_any_ip = false;
|
||||
auto ip_addr = IPAddr::createIPAddr(ip);
|
||||
if (!ip_addr.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Could not create IP address. Error: " << ip_addr.getErr();
|
||||
} else {
|
||||
parsed_ip = ConvertToIpAddress(ip_addr.unpackMove());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IpAddress
|
||||
RuleAsset::AssetUrl::ConvertToIpAddress(const IPAddr &addr)
|
||||
{
|
||||
IpAddress address;
|
||||
switch (addr.getType()) {
|
||||
case IPType::UNINITIALIZED: {
|
||||
address.addr4_t = {0};
|
||||
address.ip_type = IP_VERSION_ANY;
|
||||
break;
|
||||
}
|
||||
case IPType::V4: {
|
||||
address.addr4_t = addr.getIPv4();
|
||||
address.ip_type = IP_VERSION_4;
|
||||
break;
|
||||
}
|
||||
case IPType::V6: {
|
||||
address.addr6_t = addr.getIPv6();
|
||||
address.ip_type = IP_VERSION_6;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
address.addr4_t = {0};
|
||||
address.ip_type = IP_VERSION_ANY;
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Unsupported IP type: " << static_cast<int>(addr.getType());
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
const Assets Assets::empty_assets_config = Assets();
|
||||
|
||||
void
|
||||
Assets::preload()
|
||||
{
|
||||
registerExpectedSetting<Assets>("rulebase", "usedAssets");
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
// 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 "generic_rulebase/evaluators/asset_eval.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "generic_rulebase/assets_config.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
string AssetMatcher::ctx_key = "asset_id";
|
||||
|
||||
AssetMatcher::AssetMatcher(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() != 1) reportWrongNumberOfParams(AssetMatcher::getName(), params.size(), 1, 1);
|
||||
asset_id = params[0];
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
AssetMatcher::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<AssetMatcher>();
|
||||
auto bc_asset_id_ctx = env->get<GenericConfigId>(AssetMatcher::ctx_key);
|
||||
|
||||
if (bc_asset_id_ctx.ok()) {
|
||||
dbgTrace(D_RULEBASE_CONFIG)
|
||||
<< "Asset ID: "
|
||||
<< asset_id
|
||||
<< "; Current set assetId context: "
|
||||
<< *bc_asset_id_ctx;
|
||||
} else {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Asset ID: " << asset_id << ". Empty context";
|
||||
}
|
||||
|
||||
return bc_asset_id_ctx.ok() && *bc_asset_id_ctx == asset_id;
|
||||
}
|
@ -1,299 +0,0 @@
|
||||
// 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 "generic_rulebase/evaluators/connection_eval.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "generic_rulebase/rulebase_config.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "ip_utilities.h"
|
||||
|
||||
using namespace std;
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
string IpAddressMatcher::ctx_key = "ipAddress";
|
||||
string SourceIpMatcher::ctx_key = "sourceIP";
|
||||
string DestinationIpMatcher::ctx_key = "destinationIP";
|
||||
string SourcePortMatcher::ctx_key = "sourcePort";
|
||||
string ListeningPortMatcher::ctx_key = "listeningPort";
|
||||
string IpProtocolMatcher::ctx_key = "ipProtocol";
|
||||
string UrlMatcher::ctx_key = "url";
|
||||
|
||||
Maybe<IPAddr>
|
||||
getIpAddrFromEnviroment(I_Environment *env, Context::MetaDataType enum_data_type, const string &str_data_type)
|
||||
{
|
||||
auto ip_str = env->get<string>(enum_data_type);
|
||||
if (!ip_str.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to get " << str_data_type << " from the enviroment.";
|
||||
return genError("Failed to get " + str_data_type + " from the enviroment.");
|
||||
}
|
||||
return IPAddr::createIPAddr(ip_str.unpack());
|
||||
}
|
||||
|
||||
bool
|
||||
checkIfIpInRangesVec(const vector<CustomRange<IPAddr>> &values, const IPAddr &ip_to_check)
|
||||
{
|
||||
if (values.size() == 0) {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Ip addersses vector empty. Match is true.";
|
||||
return true;
|
||||
}
|
||||
for (const CustomRange<IPAddr> &range : values) {
|
||||
if (range.contains(ip_to_check)) {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Ip adderss matched: " << ip_to_check;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Ip adderss not match: " << ip_to_check;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
IpAddressMatcher::IpAddressMatcher(const vector<string> ¶ms)
|
||||
{
|
||||
for (const string ¶m : params) {
|
||||
Maybe<CustomRange<IPAddr>> ip_range = CustomRange<IPAddr>::createRange(param);
|
||||
if (!ip_range.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to create ip. Error: " + ip_range.getErr();
|
||||
continue;
|
||||
}
|
||||
values.push_back(ip_range.unpack());
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
IpAddressMatcher::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<IpAddressMatcher>();
|
||||
Maybe<IPAddr> subject_ip = getIpAddrFromEnviroment(
|
||||
env,
|
||||
Context::MetaDataType::SubjectIpAddr,
|
||||
"subject ip address"
|
||||
);
|
||||
if (subject_ip.ok() && checkIfIpInRangesVec(values, subject_ip.unpack())) return true;
|
||||
|
||||
Maybe<IPAddr> other_ip = getIpAddrFromEnviroment(
|
||||
env,
|
||||
Context::MetaDataType::OtherIpAddr,
|
||||
"other ip address"
|
||||
);
|
||||
if (other_ip.ok() && checkIfIpInRangesVec(values, other_ip.unpack())) return true;
|
||||
if (!subject_ip.ok() && !other_ip.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Error in getting subject ip and other ip from the enviroment";
|
||||
return false;
|
||||
}
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Ip adderss didn't match";
|
||||
return false;
|
||||
}
|
||||
|
||||
SourceIpMatcher::SourceIpMatcher(const vector<string> ¶ms)
|
||||
{
|
||||
for (const string ¶m : params) {
|
||||
Maybe<CustomRange<IPAddr>> ip_range = CustomRange<IPAddr>::createRange(param);
|
||||
if (!ip_range.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to create source ip. Error: " + ip_range.getErr();
|
||||
continue;
|
||||
}
|
||||
values.push_back(ip_range.unpack());
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
SourceIpMatcher::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<SourceIpMatcher>();
|
||||
auto direction_maybe = env->get<string>(Context::MetaDataType::Direction);
|
||||
if (!direction_maybe.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to get direction from the enviroment.";
|
||||
return false;
|
||||
}
|
||||
string direction = direction_maybe.unpack();
|
||||
if (direction == "incoming") {
|
||||
Maybe<IPAddr> other_ip = getIpAddrFromEnviroment(
|
||||
env,
|
||||
Context::MetaDataType::OtherIpAddr,
|
||||
"other ip address"
|
||||
);
|
||||
return other_ip.ok() && checkIfIpInRangesVec(values, other_ip.unpack());
|
||||
} else if (direction == "outgoing") {
|
||||
Maybe<IPAddr> subject_ip = getIpAddrFromEnviroment(
|
||||
env,
|
||||
Context::MetaDataType::SubjectIpAddr,
|
||||
"subject ip address"
|
||||
);
|
||||
return subject_ip.ok() && checkIfIpInRangesVec(values, subject_ip.unpack());
|
||||
}
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Source ip adderss didn't match";
|
||||
return false;
|
||||
}
|
||||
|
||||
DestinationIpMatcher::DestinationIpMatcher(const vector<string> ¶ms)
|
||||
{
|
||||
for (const string ¶m : params) {
|
||||
Maybe<CustomRange<IPAddr>> ip_range = CustomRange<IPAddr>::createRange(param);
|
||||
if (!ip_range.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to create destination ip. Error: " + ip_range.getErr();
|
||||
continue;
|
||||
}
|
||||
values.push_back(ip_range.unpack());
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
DestinationIpMatcher::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<DestinationIpMatcher>();
|
||||
auto direction_maybe = env->get<string>(Context::MetaDataType::Direction);
|
||||
if (!direction_maybe.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to get direction.";
|
||||
return false;
|
||||
}
|
||||
string direction = direction_maybe.unpack();
|
||||
if (direction == "outgoing") {
|
||||
Maybe<IPAddr> other_ip = getIpAddrFromEnviroment(
|
||||
env,
|
||||
Context::MetaDataType::OtherIpAddr,
|
||||
"other ip address"
|
||||
);
|
||||
return other_ip.ok() && checkIfIpInRangesVec(values, other_ip.unpack());
|
||||
} else if (direction == "incoming") {
|
||||
Maybe<IPAddr> subject_ip = getIpAddrFromEnviroment(
|
||||
env,
|
||||
Context::MetaDataType::SubjectIpAddr,
|
||||
"subject ip address"
|
||||
);
|
||||
return subject_ip.ok() && checkIfIpInRangesVec(values, subject_ip.unpack());
|
||||
}
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Destination ip adderss didn't match";
|
||||
return false;
|
||||
}
|
||||
|
||||
SourcePortMatcher::SourcePortMatcher(const vector<string> ¶ms)
|
||||
{
|
||||
for (const string ¶m : params) {
|
||||
Maybe<CustomRange<PortNumber>> port_range = CustomRange<PortNumber>::createRange(param);
|
||||
if (!port_range.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to create source port.";
|
||||
continue;
|
||||
}
|
||||
values.push_back(port_range.unpack());
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
SourcePortMatcher::evalVariable() const
|
||||
{
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Source is not a match";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ListeningPortMatcher::ListeningPortMatcher(const vector<string> ¶ms)
|
||||
{
|
||||
for (const string ¶m : params) {
|
||||
Maybe<CustomRange<PortNumber>> port_range = CustomRange<PortNumber>::createRange(param);
|
||||
if (!port_range.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to create listening port range.";
|
||||
continue;
|
||||
}
|
||||
values.push_back(port_range.unpack());
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
ListeningPortMatcher::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<ListeningPortMatcher>();
|
||||
auto port_str = env->get<string>(Context::MetaDataType::Port);
|
||||
if (!port_str.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to get port from the enviroment.";
|
||||
return false;
|
||||
}
|
||||
PortNumber port;
|
||||
if (ConnKeyUtil::fromString(port_str.unpack(), port)) {
|
||||
if (values.size() == 0) return true;
|
||||
for (const CustomRange<PortNumber> &port_range : values) {
|
||||
if (port_range.contains(port)) {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Listening port is a match. Value: " << port_str.unpack();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Listening port is not a match. Value: " << port_str.unpack();
|
||||
return false;
|
||||
}
|
||||
|
||||
IpProtocolMatcher::IpProtocolMatcher(const vector<string> ¶ms)
|
||||
{
|
||||
for (const string ¶m : params) {
|
||||
Maybe<CustomRange<IPProto>> proto_range = CustomRange<IPProto>::createRange(param);
|
||||
if (!proto_range.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to create ip protocol.";
|
||||
continue;
|
||||
}
|
||||
values.push_back(proto_range.unpack());
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
IpProtocolMatcher::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<IpProtocolMatcher>();
|
||||
auto proto_str = env->get<string>(Context::MetaDataType::Protocol);
|
||||
if (!proto_str.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to get ip protocol from the enviroment.";
|
||||
return false;
|
||||
}
|
||||
IPProto protocol;
|
||||
if (ConnKeyUtil::fromString(proto_str.unpack(), protocol)) {
|
||||
if (values.size() == 0) return true;
|
||||
for (const CustomRange<IPProto> &proto_range : values) {
|
||||
if (proto_range.contains(protocol)) {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Ip protocol is a match. Value: " << proto_str.unpack();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Source port is not a match. Value: " << proto_str.unpack();
|
||||
return false;
|
||||
}
|
||||
|
||||
UrlMatcher::UrlMatcher(const vector<string> ¶ms) : values(params) {}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
UrlMatcher::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<UrlMatcher>();
|
||||
auto curr_url_ctx = env->get<string>(Context::MetaDataType::Url);
|
||||
if (!curr_url_ctx.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to get URL from the enviroment.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (values.size() == 0) {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Matched URL on \"any\". Url: " << *curr_url_ctx;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const string &url : values) {
|
||||
if (*curr_url_ctx == url) {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Matched URL. Value: " << *curr_url_ctx;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "URL is not a match. Value: " << *curr_url_ctx;
|
||||
return false;
|
||||
}
|
@ -1,168 +0,0 @@
|
||||
// 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 "generic_rulebase/evaluators/http_transaction_data_eval.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
#include "http_transaction_data.h"
|
||||
#include "environment/evaluator_templates.h"
|
||||
#include "i_environment.h"
|
||||
#include "singleton.h"
|
||||
#include "debug.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
using namespace std;
|
||||
using namespace EnvironmentHelper;
|
||||
|
||||
EqualHost::EqualHost(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() != 1) reportWrongNumberOfParams("EqualHost", params.size(), 1, 1);
|
||||
host = params[0];
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
EqualHost::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<EqualHost>();
|
||||
auto host_ctx = env->get<string>(HttpTransactionData::host_name_ctx);
|
||||
|
||||
if (!host_ctx.ok())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string lower_host_ctx = host_ctx.unpack();
|
||||
std::transform(lower_host_ctx.begin(), lower_host_ctx.end(), lower_host_ctx.begin(), ::tolower);
|
||||
|
||||
std::string lower_host = host;
|
||||
std::transform(lower_host.begin(), lower_host.end(), lower_host.begin(), ::tolower);
|
||||
|
||||
|
||||
if (lower_host_ctx == lower_host) return true;
|
||||
size_t pos = lower_host_ctx.find_last_of(':');
|
||||
if (pos == string::npos) return false;
|
||||
lower_host_ctx = string(lower_host_ctx.data(), pos);
|
||||
return lower_host_ctx == lower_host;
|
||||
}
|
||||
|
||||
WildcardHost::WildcardHost(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() != 1) reportWrongNumberOfParams("WildcardHost", params.size(), 1, 1);
|
||||
host = params[0];
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
WildcardHost::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<WildcardHost>();
|
||||
auto host_ctx = env->get<string>(HttpTransactionData::host_name_ctx);
|
||||
|
||||
if (!host_ctx.ok())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string lower_host_ctx = host_ctx.unpack();
|
||||
transform(lower_host_ctx.begin(), lower_host_ctx.end(), lower_host_ctx.begin(), ::tolower);
|
||||
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "found host in current context: " << lower_host_ctx;
|
||||
|
||||
size_t pos = lower_host_ctx.find_first_of(".");
|
||||
if (pos == string::npos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lower_host_ctx = "*" + lower_host_ctx.substr(pos, lower_host_ctx.length());
|
||||
|
||||
string lower_host = host;
|
||||
transform(lower_host.begin(), lower_host.end(), lower_host.begin(), ::tolower);
|
||||
|
||||
dbgTrace(D_RULEBASE_CONFIG)
|
||||
<< "trying to match host context with its corresponding wildcard address: "
|
||||
<< lower_host_ctx
|
||||
<< ". Matcher host: "
|
||||
<< lower_host;
|
||||
|
||||
if (lower_host_ctx == lower_host) return true;
|
||||
pos = lower_host_ctx.find_last_of(':');
|
||||
if (pos == string::npos) return false;
|
||||
lower_host_ctx = string(lower_host_ctx.data(), pos);
|
||||
return lower_host_ctx == lower_host;
|
||||
}
|
||||
|
||||
EqualListeningIP::EqualListeningIP(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() != 1) reportWrongNumberOfParams("EqualListeningIP", params.size(), 1, 1);
|
||||
|
||||
auto maybe_ip = IPAddr::createIPAddr(params[0]);
|
||||
if (!maybe_ip.ok()) reportWrongParamType(getName(), params[0], "Not a valid IP Address");
|
||||
|
||||
listening_ip = maybe_ip.unpack();
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
EqualListeningIP::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<EqualListeningIP>();
|
||||
auto listening_ip_ctx = env->get<IPAddr>(HttpTransactionData::listening_ip_ctx);
|
||||
return listening_ip_ctx.ok() && listening_ip_ctx.unpack() == listening_ip;
|
||||
}
|
||||
|
||||
EqualListeningPort::EqualListeningPort(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() != 1) reportWrongNumberOfParams("EqualListeningPort", params.size(), 1, 1);
|
||||
|
||||
try {
|
||||
listening_port = boost::lexical_cast<PortNumber>(params[0]);
|
||||
} catch (boost::bad_lexical_cast const&) {
|
||||
reportWrongParamType(getName(), params[0], "Not a valid port number");
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
EqualListeningPort::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<EqualListeningPort>();
|
||||
auto port_ctx = env->get<PortNumber>(HttpTransactionData::listening_port_ctx);
|
||||
|
||||
return port_ctx.ok() && port_ctx.unpack() == listening_port;
|
||||
}
|
||||
|
||||
BeginWithUri::BeginWithUri(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() != 1) reportWrongNumberOfParams("BeginWithUri", params.size(), 1, 1);
|
||||
uri_prefix = params[0];
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
BeginWithUri::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<BeginWithUri>();
|
||||
auto uri_ctx = env->get<string>(HttpTransactionData::uri_ctx);
|
||||
|
||||
if (!uri_ctx.ok())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string lower_uri_ctx = uri_ctx.unpack();
|
||||
std::transform(lower_uri_ctx.begin(), lower_uri_ctx.end(), lower_uri_ctx.begin(), ::tolower);
|
||||
|
||||
std::string lower_uri_prefix = uri_prefix;
|
||||
std::transform(lower_uri_prefix.begin(), lower_uri_prefix.end(), lower_uri_prefix.begin(), ::tolower);
|
||||
|
||||
return lower_uri_ctx.find(lower_uri_prefix) == 0;
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// 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 "generic_rulebase/evaluators/parameter_eval.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "generic_rulebase/rulebase_config.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
string ParameterMatcher::ctx_key = "parameters";
|
||||
|
||||
ParameterMatcher::ParameterMatcher(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() != 1) reportWrongNumberOfParams(ParameterMatcher::getName(), params.size(), 1, 1);
|
||||
parameter_id = params[0];
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
ParameterMatcher::evalVariable() const
|
||||
{
|
||||
auto rule = getConfiguration<BasicRuleConfig>("rulebase", "rulesConfig");
|
||||
return rule.ok() && rule.unpack().isParameterActive(parameter_id);
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
// 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 "generic_rulebase/evaluators/practice_eval.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "generic_rulebase/rulebase_config.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
using namespace std;
|
||||
|
||||
string PracticeMatcher::ctx_key = "practices";
|
||||
|
||||
PracticeMatcher::PracticeMatcher(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() != 1) reportWrongNumberOfParams(PracticeMatcher::getName(), params.size(), 1, 1);
|
||||
practice_id = params[0];
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
PracticeMatcher::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<PracticeMatcher>();
|
||||
auto bc_practice_id_ctx = env->get<set<GenericConfigId>>(PracticeMatcher::ctx_key);
|
||||
dbgTrace(D_RULEBASE_CONFIG)
|
||||
<< "Trying to match practice. ID: "
|
||||
<< practice_id << ", Current set IDs: "
|
||||
<< makeSeparatedStr(bc_practice_id_ctx.ok() ? *bc_practice_id_ctx : set<GenericConfigId>(), ", ");
|
||||
if (bc_practice_id_ctx.ok()) {
|
||||
return bc_practice_id_ctx.unpack().count(practice_id) > 0;
|
||||
}
|
||||
|
||||
auto rule = getConfiguration<BasicRuleConfig>("rulebase", "rulesConfig");
|
||||
return rule.ok() && rule.unpack().isPracticeActive(practice_id);
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
// 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 "generic_rulebase/evaluators/query_eval.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "generic_rulebase/rulebase_config.h"
|
||||
#include "generic_rulebase/zones_config.h"
|
||||
#include "i_environment.h"
|
||||
#include "singleton.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "enum_range.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
QueryMatcher::QueryMatcher(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() < 1) reportWrongNumberOfParams(QueryMatcher::getName(), params.size(), 1);
|
||||
|
||||
key = params.front();
|
||||
if (key == "any") {
|
||||
is_any = true;
|
||||
} else {
|
||||
values.reserve(params.size() - 1);
|
||||
for (uint i = 1; i < params.size() ; i++) {
|
||||
if (params[i] == "any") {
|
||||
values.clear();
|
||||
break;
|
||||
}
|
||||
values.insert(params[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const string
|
||||
QueryMatcher::contextKeyToString(Context::MetaDataType type)
|
||||
{
|
||||
if (type == Context::MetaDataType::SubjectIpAddr || type == Context::MetaDataType::OtherIpAddr) return "ip";
|
||||
return Context::convertToString(type);
|
||||
}
|
||||
|
||||
class QueryMatchSerializer
|
||||
{
|
||||
public:
|
||||
static const string req_attr_ctx_key;
|
||||
|
||||
template <typename Archive>
|
||||
void
|
||||
serialize(Archive &ar)
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<QueryMatcher>();
|
||||
auto req_attr = env->get<string>(req_attr_ctx_key);
|
||||
if (!req_attr.ok()) return;
|
||||
|
||||
try {
|
||||
ar(cereal::make_nvp(*req_attr, value));
|
||||
dbgDebug(D_RULEBASE_CONFIG)
|
||||
<< "Found value for requested attribute. Tag: "
|
||||
<< *req_attr
|
||||
<< ", Value: "
|
||||
<< value;
|
||||
} catch (exception &e) {
|
||||
dbgDebug(D_RULEBASE_CONFIG) << "Could not find values for requested attribute. Tag: " << *req_attr;
|
||||
ar.finishNode();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Values>
|
||||
bool
|
||||
matchValues(const Values &requested_vals) const
|
||||
{
|
||||
return value != "" && (requested_vals.empty() || requested_vals.count(value) > 0);
|
||||
}
|
||||
|
||||
private:
|
||||
string value;
|
||||
};
|
||||
|
||||
const string QueryMatchSerializer::req_attr_ctx_key = "requested attribute key";
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
QueryMatcher::evalVariable() const
|
||||
{
|
||||
if (is_any) return true;
|
||||
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<QueryMatcher>();
|
||||
auto local_asset_ctx = env->get<bool>("is local asset");
|
||||
bool is_remote_asset = local_asset_ctx.ok() && !(*local_asset_ctx);
|
||||
|
||||
QueryRequest request;
|
||||
for (Context::MetaDataType name : makeRange<Context::MetaDataType>()) {
|
||||
auto val = env->get<string>(name);
|
||||
if (val.ok()) {
|
||||
if ((name == Context::MetaDataType::SubjectIpAddr && is_remote_asset) ||
|
||||
(name == Context::MetaDataType::OtherIpAddr && !is_remote_asset)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
request.addCondition(Condition::EQUALS, contextKeyToString(name), *val);
|
||||
}
|
||||
}
|
||||
if (request.empty()) return false;
|
||||
|
||||
request.setRequestedAttr(key);
|
||||
ScopedContext req_attr_key;
|
||||
req_attr_key.registerValue<string>(QueryMatchSerializer::req_attr_ctx_key, key);
|
||||
|
||||
I_Intelligence_IS_V2 *intelligence = Singleton::Consume<I_Intelligence_IS_V2>::by<Zone>();
|
||||
auto query_res = intelligence->queryIntelligence<QueryMatchSerializer>(request);
|
||||
if (!query_res.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to perform intelligence query. Error: " << query_res.getErr();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const AssetReply<QueryMatchSerializer> &asset : query_res.unpack()) {
|
||||
if (asset.matchValues<unordered_set<string>>(values)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
// 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 "generic_rulebase/evaluators/trigger_eval.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "generic_rulebase/rulebase_config.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
string TriggerMatcher::ctx_key = "triggers";
|
||||
|
||||
TriggerMatcher::TriggerMatcher(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() != 1) reportWrongNumberOfParams(TriggerMatcher::getName(), params.size(), 1, 1);
|
||||
trigger_id = params[0];
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
TriggerMatcher::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<TriggerMatcher>();
|
||||
auto ac_bc_trigger_id_ctx = env->get<set<GenericConfigId>>("ac_trigger_id");
|
||||
dbgTrace(D_RULEBASE_CONFIG)
|
||||
<< "Trying to match trigger for access control rule. ID: "
|
||||
<< trigger_id << ", Current set IDs: "
|
||||
<< makeSeparatedStr(ac_bc_trigger_id_ctx.ok() ? *ac_bc_trigger_id_ctx : set<GenericConfigId>(), ", ");
|
||||
if (ac_bc_trigger_id_ctx.ok()) {
|
||||
return ac_bc_trigger_id_ctx.unpack().count(trigger_id) > 0;
|
||||
}
|
||||
|
||||
auto bc_trigger_id_ctx = env->get<set<GenericConfigId>>(TriggerMatcher::ctx_key);
|
||||
dbgTrace(D_RULEBASE_CONFIG)
|
||||
<< "Trying to match trigger. ID: "
|
||||
<< trigger_id << ", Current set IDs: "
|
||||
<< makeSeparatedStr(bc_trigger_id_ctx.ok() ? *bc_trigger_id_ctx : set<GenericConfigId>(), ", ");
|
||||
if (bc_trigger_id_ctx.ok() && bc_trigger_id_ctx.unpack().count(trigger_id) > 0 ) return true;
|
||||
|
||||
auto rule = getConfiguration<BasicRuleConfig>("rulebase", "rulesConfig");
|
||||
return rule.ok() && rule.unpack().isTriggerActive(trigger_id);
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
// 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 "generic_rulebase/evaluators/zone_eval.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "generic_rulebase/zone.h"
|
||||
#include "generic_rulebase/rulebase_config.h"
|
||||
#include "config.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
string ZoneMatcher::ctx_key = "zone_id";
|
||||
|
||||
ZoneMatcher::ZoneMatcher(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() != 1) reportWrongNumberOfParams(ZoneMatcher::getName(), params.size(), 1, 1);
|
||||
zone_id = params[0];
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
ZoneMatcher::evalVariable() const
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<ZoneMatcher>();
|
||||
auto bc_zone_id_ctx = env->get<GenericConfigId>(ZoneMatcher::ctx_key);
|
||||
if (bc_zone_id_ctx.ok() && *bc_zone_id_ctx == zone_id) return true;
|
||||
|
||||
if (!getProfileAgentSettingWithDefault<bool>(false, "rulebase.enableQueryBasedMatch")) return false;
|
||||
|
||||
auto zone = getConfiguration<Zone>("rulebase", "zones");
|
||||
return zone.ok() && zone.unpack().getId() == zone_id;
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
// 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 "generic_rulebase/generic_rulebase.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include "generic_rulebase/evaluators/trigger_eval.h"
|
||||
#include "generic_rulebase/evaluators/practice_eval.h"
|
||||
#include "generic_rulebase/evaluators/parameter_eval.h"
|
||||
#include "generic_rulebase/evaluators/zone_eval.h"
|
||||
#include "generic_rulebase/evaluators/asset_eval.h"
|
||||
#include "generic_rulebase/evaluators/query_eval.h"
|
||||
#include "generic_rulebase/evaluators/connection_eval.h"
|
||||
#include "generic_rulebase/evaluators/http_transaction_data_eval.h"
|
||||
#include "generic_rulebase/zone.h"
|
||||
#include "generic_rulebase/triggers_config.h"
|
||||
#include "singleton.h"
|
||||
#include "common.h"
|
||||
#include "debug.h"
|
||||
#include "cache.h"
|
||||
#include "config.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
class GenericRulebase::Impl : Singleton::Provide<I_GenericRulebase>::From<GenericRulebase>
|
||||
{
|
||||
public:
|
||||
void init() {}
|
||||
void fini() {}
|
||||
|
||||
void preload();
|
||||
|
||||
Maybe<Zone, Config::Errors> getLocalZone() const override { return getZoneConfig(true); }
|
||||
Maybe<Zone, Config::Errors> getOtherZone() const override { return getZoneConfig(false); }
|
||||
|
||||
set<ParameterBehavior> getBehavior(const ParameterKeyValues &key_value_pairs) const override;
|
||||
|
||||
private:
|
||||
Maybe<Zone, Config::Errors>
|
||||
getZoneConfig(bool is_local_zone) const
|
||||
{
|
||||
ScopedContext asset_location_ctx;
|
||||
asset_location_ctx.registerValue<bool>("is local asset", is_local_zone);
|
||||
return getConfiguration<Zone>("rulebase", "zones");
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
GenericRulebase::Impl::preload()
|
||||
{
|
||||
addMatcher<TriggerMatcher>();
|
||||
addMatcher<PracticeMatcher>();
|
||||
addMatcher<ParameterMatcher>();
|
||||
addMatcher<ZoneMatcher>();
|
||||
addMatcher<AssetMatcher>();
|
||||
addMatcher<QueryMatcher>();
|
||||
addMatcher<IpAddressMatcher>();
|
||||
addMatcher<SourceIpMatcher>();
|
||||
addMatcher<DestinationIpMatcher>();
|
||||
addMatcher<SourcePortMatcher>();
|
||||
addMatcher<ListeningPortMatcher>();
|
||||
addMatcher<IpProtocolMatcher>();
|
||||
addMatcher<UrlMatcher>();
|
||||
addMatcher<EqualHost>();
|
||||
addMatcher<WildcardHost>();
|
||||
addMatcher<EqualListeningIP>();
|
||||
addMatcher<EqualListeningPort>();
|
||||
addMatcher<BeginWithUri>();
|
||||
BasicRuleConfig::preload();
|
||||
LogTriggerConf::preload();
|
||||
ParameterException::preload();
|
||||
registerExpectedConfiguration<Zone>("rulebase", "zones");
|
||||
registerExpectedConfigFile("zones", Config::ConfigFileType::Policy);
|
||||
registerExpectedConfigFile("triggers", Config::ConfigFileType::Policy);
|
||||
registerExpectedConfigFile("rules", Config::ConfigFileType::Policy);
|
||||
registerExpectedConfigFile("parameters", Config::ConfigFileType::Policy);
|
||||
registerExpectedConfigFile("exceptions", Config::ConfigFileType::Policy);
|
||||
|
||||
}
|
||||
|
||||
set<ParameterBehavior>
|
||||
GenericRulebase::Impl::getBehavior(const ParameterKeyValues &key_value_pairs) const
|
||||
{
|
||||
auto &exceptions = getConfiguration<ParameterException>("rulebase", "exception");
|
||||
|
||||
if (!exceptions.ok()) {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Could not find any exception with the current rule's context";
|
||||
return {};
|
||||
}
|
||||
return (*exceptions).getBehavior(key_value_pairs);
|
||||
}
|
||||
|
||||
GenericRulebase::GenericRulebase() : Component("GenericRulebase"), pimpl(make_unique<Impl>()) {}
|
||||
|
||||
GenericRulebase::~GenericRulebase() {}
|
||||
|
||||
void
|
||||
GenericRulebase::init()
|
||||
{
|
||||
pimpl->init();
|
||||
}
|
||||
|
||||
void
|
||||
GenericRulebase::fini()
|
||||
{
|
||||
pimpl->fini();
|
||||
}
|
||||
|
||||
void
|
||||
GenericRulebase::preload()
|
||||
{
|
||||
pimpl->preload();
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
// 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 "generic_rulebase/generic_rulebase_context.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "context.h"
|
||||
#include "config.h"
|
||||
#include "generic_rulebase/evaluators/trigger_eval.h"
|
||||
#include "generic_rulebase/evaluators/parameter_eval.h"
|
||||
#include "generic_rulebase/evaluators/practice_eval.h"
|
||||
#include "generic_rulebase/evaluators/zone_eval.h"
|
||||
#include "generic_rulebase/evaluators/asset_eval.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
using namespace std;
|
||||
|
||||
template<typename Configs>
|
||||
set<GenericConfigId>
|
||||
extractIds(const vector<Configs> &configurations)
|
||||
{
|
||||
set<GenericConfigId> ids;
|
||||
for (const Configs &conf : configurations) {
|
||||
ids.insert(conf.getId());
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
void
|
||||
GenericRulebaseContext::activate(const BasicRuleConfig &rule)
|
||||
{
|
||||
switch(registration_state) {
|
||||
case RuleRegistrationState::UNINITIALIZED: {
|
||||
registration_state = RuleRegistrationState::REGISTERED;
|
||||
ctx.registerValue<set<GenericConfigId>>(
|
||||
TriggerMatcher::ctx_key,
|
||||
extractIds<RuleTrigger>(rule.getTriggers())
|
||||
);
|
||||
ctx.registerValue<set<GenericConfigId>>(
|
||||
PracticeMatcher::ctx_key,
|
||||
extractIds<RulePractice>(rule.getPractices())
|
||||
);
|
||||
dbgTrace(D_RULEBASE_CONFIG)
|
||||
<< "Activating current practices. Current practice IDs: "
|
||||
<< makeSeparatedStr(extractIds<RulePractice>(rule.getPractices()), ", ");
|
||||
|
||||
ctx.registerValue<set<GenericConfigId>>(
|
||||
ParameterMatcher::ctx_key,
|
||||
extractIds<RuleParameter>(rule.getParameters())
|
||||
);
|
||||
ctx.registerValue<GenericConfigId>(
|
||||
ZoneMatcher::ctx_key,
|
||||
rule.getZoneId()
|
||||
);
|
||||
ctx.registerValue<GenericConfigId>(
|
||||
AssetMatcher::ctx_key,
|
||||
rule.getAssetId()
|
||||
);
|
||||
ctx.activate();
|
||||
break;
|
||||
}
|
||||
case RuleRegistrationState::REGISTERED: {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Activating registered rule values";
|
||||
ctx.activate();
|
||||
break;
|
||||
}
|
||||
case RuleRegistrationState::UNREGISTERED: {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Failed to register rule values";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GenericRulebaseContext::activate()
|
||||
{
|
||||
switch(registration_state) {
|
||||
case RuleRegistrationState::UNINITIALIZED: {
|
||||
auto maybe_rule = getConfiguration<BasicRuleConfig>("rulebase", "rulesConfig");
|
||||
if (!maybe_rule.ok()) {
|
||||
registration_state = RuleRegistrationState::UNREGISTERED;
|
||||
return;
|
||||
}
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Registering new rule values";
|
||||
activate(maybe_rule.unpack());
|
||||
registration_state = RuleRegistrationState::REGISTERED;
|
||||
break;
|
||||
}
|
||||
case RuleRegistrationState::REGISTERED: {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Activating registered rule values";
|
||||
ctx.activate();
|
||||
break;
|
||||
}
|
||||
case RuleRegistrationState::UNREGISTERED: {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Failed to register rule values";
|
||||
}
|
||||
}
|
||||
}
|
@ -1,347 +0,0 @@
|
||||
// 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 "generic_rulebase/match_query.h"
|
||||
|
||||
#include "cereal/types/set.hpp"
|
||||
|
||||
#include "generic_rulebase/generic_rulebase_utils.h"
|
||||
#include "config.h"
|
||||
#include "ip_utilities.h"
|
||||
#include "agent_core_utilities.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const unordered_map<string, MatchQuery::MatchType> string_to_match_type = {
|
||||
{ "condition", MatchQuery::MatchType::Condition },
|
||||
{ "operator", MatchQuery::MatchType::Operator }
|
||||
};
|
||||
|
||||
static const unordered_map<string, MatchQuery::Operators> string_to_operator = {
|
||||
{ "and", MatchQuery::Operators::And },
|
||||
{ "or", MatchQuery::Operators::Or }
|
||||
};
|
||||
|
||||
static const unordered_map<string, MatchQuery::Conditions> string_to_condition = {
|
||||
{ "equals", MatchQuery::Conditions::Equals },
|
||||
{ "not-equals", MatchQuery::Conditions::NotEquals },
|
||||
{ "not equals", MatchQuery::Conditions::NotEquals },
|
||||
{ "in", MatchQuery::Conditions::In },
|
||||
{ "not-in", MatchQuery::Conditions::NotIn },
|
||||
{ "not in", MatchQuery::Conditions::NotIn },
|
||||
{ "exist", MatchQuery::Conditions::Exist }
|
||||
};
|
||||
|
||||
static const string ip_addr_type_name = "IP address";
|
||||
static const string port_type_name = "port";
|
||||
static const string ip_proto_type_name = "IP protocol";
|
||||
|
||||
static const unordered_map<string, MatchQuery::StaticKeys> string_to_key = {
|
||||
{ "sourceIP", MatchQuery::StaticKeys::SrcIpAddress },
|
||||
{ "sourceIpAddr", MatchQuery::StaticKeys::SrcIpAddress },
|
||||
{ "destinationIP", MatchQuery::StaticKeys::DstIpAddress },
|
||||
{ "destinationIpAddr", MatchQuery::StaticKeys::DstIpAddress },
|
||||
{ "ipAddress", MatchQuery::StaticKeys::IpAddress },
|
||||
{ "sourcePort", MatchQuery::StaticKeys::SrcPort },
|
||||
{ "listeningPort", MatchQuery::StaticKeys::ListeningPort },
|
||||
{ "ipProtocol", MatchQuery::StaticKeys::IpProtocol },
|
||||
{ "domain", MatchQuery::StaticKeys::Domain }
|
||||
};
|
||||
|
||||
MatchQuery::MatchQuery(const string &match) : is_specific_label(false), is_ignore_keyword(false)
|
||||
{
|
||||
try {
|
||||
stringstream ss;
|
||||
ss.str(match);
|
||||
cereal::JSONInputArchive archive_in(ss);
|
||||
load(archive_in);
|
||||
} catch (const exception &e) {
|
||||
dbgWarning(D_RULEBASE_CONFIG)
|
||||
<< "Unable to load match query JSON. JSON content: "
|
||||
<< match
|
||||
<< ", Error: "
|
||||
<< e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MatchQuery::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
string type_as_string;
|
||||
archive_in(cereal::make_nvp("type", type_as_string));
|
||||
|
||||
string op_as_string;
|
||||
archive_in(cereal::make_nvp("op", op_as_string));
|
||||
|
||||
auto maybe_type = string_to_match_type.find(type_as_string);
|
||||
if (maybe_type == string_to_match_type.end()) {
|
||||
reportConfigurationError("Illegal Zone match query type. Provided type in configuration: " + type_as_string);
|
||||
}
|
||||
|
||||
type = maybe_type->second;
|
||||
switch (type) {
|
||||
case (MatchType::Condition): {
|
||||
auto maybe_condition = string_to_condition.find(op_as_string);
|
||||
if (maybe_condition == string_to_condition.end()) {
|
||||
reportConfigurationError(
|
||||
"Illegal op provided for condition. Provided op in configuration: " +
|
||||
op_as_string
|
||||
);
|
||||
}
|
||||
condition_type = maybe_condition->second;
|
||||
operator_type = Operators::None;
|
||||
archive_in(cereal::make_nvp("key", key));
|
||||
key_type = getKeyByName(key);
|
||||
if (key_type == StaticKeys::NotStatic) {
|
||||
if (key.rfind("containerLabels.", 0) == 0) {
|
||||
is_specific_label = true;
|
||||
} else {
|
||||
is_specific_label = false;
|
||||
}
|
||||
}
|
||||
is_ignore_keyword = (key == "indicator");
|
||||
|
||||
if (condition_type != Conditions::Exist) {
|
||||
archive_in(cereal::make_nvp("value", value));
|
||||
for(const auto &val: value) {
|
||||
if (isKeyTypeIp()) {
|
||||
auto ip_range = IPUtilities::createRangeFromString<IPRange, IpAddress>(val, ip_addr_type_name);
|
||||
if (ip_range.ok()) {
|
||||
ip_addr_value.push_back(ip_range.unpack());
|
||||
} else {
|
||||
dbgWarning(D_RULEBASE_CONFIG)
|
||||
<< "Failed to parse IP address range. Error: "
|
||||
<< ip_range.getErr();
|
||||
}
|
||||
} else if (isKeyTypePort()) {
|
||||
auto port_range = IPUtilities::createRangeFromString<PortsRange, uint16_t>(
|
||||
val,
|
||||
port_type_name
|
||||
);
|
||||
if (port_range.ok()) {
|
||||
port_value.push_back(port_range.unpack());
|
||||
} else {
|
||||
dbgWarning(D_RULEBASE_CONFIG)
|
||||
<< "Failed to parse port range. Error: "
|
||||
<< port_range.getErr();
|
||||
}
|
||||
} else if (isKeyTypeProtocol()) {
|
||||
auto proto_range = IPUtilities::createRangeFromString<IpProtoRange, uint8_t>(
|
||||
val,
|
||||
ip_proto_type_name
|
||||
);
|
||||
if (proto_range.ok()) {
|
||||
ip_proto_value.push_back(proto_range.unpack());
|
||||
} else {
|
||||
dbgWarning(D_RULEBASE_CONFIG)
|
||||
<< "Failed to parse IP protocol range. Error: "
|
||||
<< proto_range.getErr();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
regex_values.insert(boost::regex(val));
|
||||
} catch (const exception &e) {
|
||||
dbgDebug(D_RULEBASE_CONFIG) << "Failed to compile regex. Error: " << e.what();
|
||||
}
|
||||
}
|
||||
first_value = *(value.begin());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (MatchType::Operator): {
|
||||
auto maybe_operator = string_to_operator.find(op_as_string);
|
||||
if (maybe_operator == string_to_operator.end()) {
|
||||
reportConfigurationError(
|
||||
"Illegal op provided for operator. Provided op in configuration: " +
|
||||
op_as_string
|
||||
);
|
||||
}
|
||||
operator_type = maybe_operator->second;
|
||||
condition_type = Conditions::None;
|
||||
archive_in(cereal::make_nvp("items", items));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MatchQuery::StaticKeys
|
||||
MatchQuery::getKeyByName(const string &key_type_name)
|
||||
{
|
||||
auto key = string_to_key.find(key_type_name);
|
||||
if (key == string_to_key.end()) return StaticKeys::NotStatic;
|
||||
return key->second;
|
||||
}
|
||||
|
||||
bool
|
||||
MatchQuery::isKeyTypeIp() const
|
||||
{
|
||||
return (key_type >= StaticKeys::IpAddress && key_type <= StaticKeys::DstIpAddress);
|
||||
}
|
||||
|
||||
bool
|
||||
MatchQuery::isKeyTypePort() const
|
||||
{
|
||||
return (key_type == StaticKeys::SrcPort || key_type == StaticKeys::ListeningPort);
|
||||
}
|
||||
|
||||
bool
|
||||
MatchQuery::isKeyTypeProtocol() const
|
||||
{
|
||||
return (key_type == StaticKeys::IpProtocol);
|
||||
}
|
||||
|
||||
bool
|
||||
MatchQuery::isKeyTypeDomain() const
|
||||
{
|
||||
return (key_type == StaticKeys::Domain);
|
||||
}
|
||||
|
||||
bool
|
||||
MatchQuery::isKeyTypeSpecificLabel() const
|
||||
{
|
||||
return is_specific_label;
|
||||
}
|
||||
|
||||
bool
|
||||
MatchQuery::isKeyTypeStatic() const
|
||||
{
|
||||
return (key_type != StaticKeys::NotStatic);
|
||||
}
|
||||
|
||||
set<string>
|
||||
MatchQuery::getAllKeys() const
|
||||
{
|
||||
set<string> keys;
|
||||
if (type == MatchType::Condition) {
|
||||
if (!key.empty()) keys.insert(key);
|
||||
return keys;
|
||||
}
|
||||
|
||||
for (const MatchQuery &inner_match: items) {
|
||||
set<string> iner_keys = inner_match.getAllKeys();
|
||||
keys.insert(iner_keys.begin(), iner_keys.end());
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
bool
|
||||
MatchQuery::matchAttributes(
|
||||
const unordered_map<string, set<string>> &key_value_pairs,
|
||||
set<string> &matched_override_keywords ) const
|
||||
{
|
||||
|
||||
if (type == MatchType::Condition) {
|
||||
auto key_value_pair = key_value_pairs.find(key);
|
||||
if (key_value_pair == key_value_pairs.end()) {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Ignoring irrelevant key: " << key;
|
||||
return false;
|
||||
}
|
||||
return matchAttributes(key_value_pair->second, matched_override_keywords);
|
||||
} else if (type == MatchType::Operator && operator_type == Operators::And) {
|
||||
for (const MatchQuery &inner_match: items) {
|
||||
if (!inner_match.matchAttributes(key_value_pairs, matched_override_keywords)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (type == MatchType::Operator && operator_type == Operators::Or) {
|
||||
// With 'or' condition, evaluate matched override keywords first and add the ones that were fully matched
|
||||
set<string> inner_override_keywords;
|
||||
bool res = false;
|
||||
for (const MatchQuery &inner_match: items) {
|
||||
inner_override_keywords.clear();
|
||||
if (inner_match.matchAttributes(key_value_pairs, inner_override_keywords)) {
|
||||
matched_override_keywords.insert(inner_override_keywords.begin(), inner_override_keywords.end());
|
||||
res = true;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Unsupported match query type";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
MatchQuery::MatchResult
|
||||
MatchQuery::getMatch( const unordered_map<string, set<string>> &key_value_pairs) const
|
||||
{
|
||||
MatchQuery::MatchResult matches;
|
||||
matches.matched_keywords = make_shared<set<string>>();
|
||||
matches.is_match = matchAttributes(key_value_pairs, *matches.matched_keywords);
|
||||
return matches;
|
||||
}
|
||||
|
||||
bool
|
||||
MatchQuery::matchAttributes(
|
||||
const unordered_map<string, set<string>> &key_value_pairs) const
|
||||
{
|
||||
return getMatch(key_value_pairs).is_match;
|
||||
}
|
||||
|
||||
bool
|
||||
MatchQuery::matchAttributes(
|
||||
const set<string> &values,
|
||||
set<string> &matched_override_keywords) const
|
||||
{
|
||||
auto &type = condition_type;
|
||||
bool negate = type == MatchQuery::Conditions::NotEquals || type == MatchQuery::Conditions::NotIn;
|
||||
bool match = isRegEx() ? matchAttributesRegEx(values, matched_override_keywords) : matchAttributesString(values);
|
||||
return negate ? !match : match;
|
||||
}
|
||||
|
||||
bool
|
||||
MatchQuery::matchAttributesRegEx(
|
||||
const set<string> &values,
|
||||
set<string> &matched_override_keywords) const
|
||||
{
|
||||
bool res = false;
|
||||
boost::cmatch value_matcher;
|
||||
for (const boost::regex &val_regex : regex_values) {
|
||||
for (const string &requested_match_value : values) {
|
||||
if (NGEN::Regex::regexMatch(
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
requested_match_value.c_str(),
|
||||
value_matcher,
|
||||
val_regex))
|
||||
{
|
||||
res = true;
|
||||
if (is_ignore_keyword) {
|
||||
matched_override_keywords.insert(requested_match_value);
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
MatchQuery::matchAttributesString(const set<string> &values) const
|
||||
{
|
||||
for (const string &requested_value : values) {
|
||||
if (value.find(requested_value) != value.end()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
MatchQuery::isRegEx() const
|
||||
{
|
||||
return key != "protectionName";
|
||||
}
|
@ -1,157 +0,0 @@
|
||||
// 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 "generic_rulebase/parameters_config.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool ParameterException::is_geo_location_exception_exists(false);
|
||||
bool ParameterException::is_geo_location_exception_being_loaded(false);
|
||||
|
||||
void
|
||||
ParameterOverrides::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
parseJSONKey<vector<ParsedBehavior>>("parsedBehavior", parsed_behaviors, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
ParameterTrustedSources::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
parseJSONKey<uint>("numOfSources", num_of_sources, archive_in);
|
||||
parseJSONKey<vector<SourcesIdentifier>>("sourcesIdentifiers", sources_identidiers, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
ParameterBehavior::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
string key_string;
|
||||
string val_string;
|
||||
parseJSONKey<string>("id", id, archive_in);
|
||||
parseJSONKey<string>("key", key_string, archive_in);
|
||||
parseJSONKey<string>("value", val_string, archive_in);
|
||||
if (string_to_behavior_key.find(key_string) == string_to_behavior_key.end()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Unsupported behavior key: " << key_string;
|
||||
return;
|
||||
}
|
||||
key = string_to_behavior_key.at(key_string);
|
||||
|
||||
if (string_to_behavior_val.find(val_string) == string_to_behavior_val.end()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Unsupported behavior value: " << val_string;
|
||||
return;
|
||||
}
|
||||
value = string_to_behavior_val.at(val_string);
|
||||
}
|
||||
|
||||
void
|
||||
ParameterAntiBot::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
parseJSONKey<vector<string>>("injected", injected, archive_in);
|
||||
parseJSONKey<vector<string>>("validated", validated, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
ParameterOAS::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
parseJSONKey<string>("value", value, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
ParameterException::MatchBehaviorPair::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
parseJSONKey<MatchQuery>("match", match, archive_in);
|
||||
parseJSONKey<ParameterBehavior>("behavior", behavior, archive_in);
|
||||
}
|
||||
|
||||
void
|
||||
ParameterException::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
try {
|
||||
archive_in(
|
||||
cereal::make_nvp("match", match),
|
||||
cereal::make_nvp("behavior", behavior)
|
||||
);
|
||||
} catch (...) {
|
||||
parseJSONKey<vector<MatchBehaviorPair>>("exceptions", match_queries, archive_in);
|
||||
}
|
||||
|
||||
function<bool(const MatchQuery &)> isGeoLocationExists =
|
||||
[&](const MatchQuery &query)
|
||||
{
|
||||
if (query.getKey() == "countryCode" || query.getKey() == "countryName") {
|
||||
is_geo_location_exception_being_loaded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const MatchQuery &query_item : query.getItems()) {
|
||||
if (isGeoLocationExists(query_item)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
if (isGeoLocationExists(match)) return;
|
||||
for (const MatchBehaviorPair &match_query : match_queries) {
|
||||
if (isGeoLocationExists(match_query.match)) return;
|
||||
}
|
||||
}
|
||||
|
||||
set<ParameterBehavior>
|
||||
ParameterException::getBehavior(
|
||||
const unordered_map<string, set<string>> &key_value_pairs,
|
||||
set<string> &matched_override_keywords) const
|
||||
{
|
||||
set<ParameterBehavior> matched_behaviors;
|
||||
|
||||
matched_override_keywords.clear();
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Matching exception";
|
||||
for (const MatchBehaviorPair &match_behavior_pair: match_queries) {
|
||||
MatchQuery::MatchResult match_res = match_behavior_pair.match.getMatch(key_value_pairs);
|
||||
if (match_res.is_match) {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Successfully matched an exception from a list of matches.";
|
||||
// When matching indicators with action=ignore, we expect no behavior override.
|
||||
// Instead, a matched keywords list should be returned which will be later removed from score calculation
|
||||
if (match_res.matched_keywords->size() > 0 && match_behavior_pair.behavior == action_ignore) {
|
||||
matched_override_keywords.insert(match_res.matched_keywords->begin(),
|
||||
match_res.matched_keywords->end());
|
||||
} else {
|
||||
matched_behaviors.insert(match_behavior_pair.behavior);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match_queries.empty()) {
|
||||
MatchQuery::MatchResult match_res = match.getMatch(key_value_pairs);
|
||||
if (match_res.is_match) {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Successfully matched an exception.";
|
||||
// When matching indicators with action=ignore, we expect no behavior override.
|
||||
// Instead, a matched keywords list should be returned which will be later removed from score calculation
|
||||
if (match_res.matched_keywords->size() > 0 && behavior == action_ignore) {
|
||||
matched_override_keywords.insert(match_res.matched_keywords->begin(),
|
||||
match_res.matched_keywords->end());
|
||||
} else {
|
||||
matched_behaviors.insert(behavior);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matched_behaviors;
|
||||
}
|
||||
|
||||
set<ParameterBehavior>
|
||||
ParameterException::getBehavior(const unordered_map<string, set<string>> &key_value_pairs) const
|
||||
{
|
||||
set<string> keywords;
|
||||
return getBehavior(key_value_pairs, keywords);
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
// 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 "generic_rulebase/rulebase_config.h"
|
||||
|
||||
#include "telemetry.h"
|
||||
#include "config.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
using namespace std;
|
||||
|
||||
set<string> BasicRuleConfig::assets_ids{};
|
||||
set<string> BasicRuleConfig::assets_ids_aggregation{};
|
||||
|
||||
void
|
||||
BasicRuleConfig::load(cereal::JSONInputArchive &ar)
|
||||
{
|
||||
parseJSONKey<vector<RulePractice>>("practices", practices, ar);
|
||||
parseJSONKey<vector<RuleTrigger>>("triggers", triggers, ar);
|
||||
parseJSONKey<vector<RuleParameter>>("parameters", parameters, ar);
|
||||
parseJSONKey<uint8_t>("priority", priority, ar);
|
||||
parseJSONKey<string>("ruleId", rule_id, ar);
|
||||
parseJSONKey<string>("ruleName", rule_name, ar);
|
||||
parseJSONKey<string>("assetId", asset_id, ar);
|
||||
parseJSONKey<string>("assetName", asset_name, ar);
|
||||
parseJSONKey<string>("zoneId", zone_id, ar);
|
||||
parseJSONKey<string>("zoneName", zone_name, ar);
|
||||
|
||||
assets_ids_aggregation.insert(asset_id);
|
||||
}
|
||||
|
||||
void
|
||||
BasicRuleConfig::updateCountMetric()
|
||||
{
|
||||
BasicRuleConfig::assets_ids = BasicRuleConfig::assets_ids_aggregation;
|
||||
AssetCountEvent(AssetType::ALL, BasicRuleConfig::assets_ids.size()).notify();
|
||||
}
|
||||
|
||||
bool
|
||||
BasicRuleConfig::isPracticeActive(const string &practice_id) const
|
||||
{
|
||||
for (auto practice: practices) {
|
||||
if (practice.getId() == practice_id) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
BasicRuleConfig::isTriggerActive(const string &trigger_id) const
|
||||
{
|
||||
for (auto trigger: triggers) {
|
||||
if (trigger.getId() == trigger_id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
BasicRuleConfig::isParameterActive(const string ¶meter_id) const
|
||||
{
|
||||
for (auto param: parameters) {
|
||||
if (param.getId() == parameter_id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
@ -1,243 +0,0 @@
|
||||
// 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 <string>
|
||||
#include <map>
|
||||
|
||||
#include "generic_rulebase/triggers_config.h"
|
||||
#include "generic_rulebase/generic_rulebase_utils.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
using namespace std;
|
||||
|
||||
WebTriggerConf::WebTriggerConf() : response_title(""), response_body(""), response_code(0) {}
|
||||
WebTriggerConf::WebTriggerConf(const string &title, const string &body, uint code)
|
||||
:
|
||||
response_title(title),
|
||||
response_body(body),
|
||||
response_code(code)
|
||||
{}
|
||||
|
||||
WebTriggerConf WebTriggerConf::default_trigger_conf = WebTriggerConf(
|
||||
"Attack blocked by web application protection", // title
|
||||
"Check Point's <b>Application Security</b> has detected an attack and blocked it.", // body
|
||||
403
|
||||
);
|
||||
|
||||
void
|
||||
WebTriggerConf::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
try {
|
||||
parseJSONKey<string>("details level", details_level, archive_in);
|
||||
if (details_level == "Redirect") {
|
||||
parseJSONKey<string>("redirect URL", redirect_url, archive_in);
|
||||
parseJSONKey<bool>("xEventId", add_event_id_to_header, archive_in);
|
||||
parseJSONKey<bool>("eventIdInHeader", add_event_id_to_header, archive_in);
|
||||
return;
|
||||
}
|
||||
parseJSONKey<uint>("response code", response_code, archive_in);
|
||||
if (response_code < 100 || response_code > 599) {
|
||||
throw cereal::Exception(
|
||||
"illegal web trigger response code: " +
|
||||
to_string(response_code) +
|
||||
" is out of range (100-599)"
|
||||
);
|
||||
}
|
||||
|
||||
if (details_level == "Response Code") return;
|
||||
|
||||
parseJSONKey<string>("response body", response_body, archive_in);
|
||||
parseJSONKey<string>("response title", response_title, archive_in);
|
||||
} catch (const exception &e) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to parse the web trigger configuration: '" << e.what() << "'";
|
||||
archive_in.setNextName(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
WebTriggerConf::operator==(const WebTriggerConf &other) const
|
||||
{
|
||||
return
|
||||
response_code == other.response_code &&
|
||||
response_title == other.response_title &&
|
||||
response_body == other.response_body;
|
||||
}
|
||||
|
||||
LogTriggerConf::LogTriggerConf(string trigger_name, bool log_detect, bool log_prevent) : name(trigger_name)
|
||||
{
|
||||
if (log_detect) should_log_on_detect.setAll();
|
||||
if (log_prevent) should_log_on_prevent.setAll();
|
||||
active_streams.setFlag(ReportIS::StreamType::JSON_FOG);
|
||||
active_streams.setFlag(ReportIS::StreamType::JSON_LOG_FILE);
|
||||
}
|
||||
|
||||
ReportIS::Severity
|
||||
LogTriggerConf::getSeverity(bool is_action_drop_or_prevent) const
|
||||
{
|
||||
return is_action_drop_or_prevent ? ReportIS::Severity::MEDIUM : ReportIS::Severity::LOW;
|
||||
}
|
||||
|
||||
ReportIS::Priority
|
||||
LogTriggerConf::getPriority(bool is_action_drop_or_prevent) const
|
||||
{
|
||||
return is_action_drop_or_prevent ? ReportIS::Priority::HIGH : ReportIS::Priority::MEDIUM;
|
||||
}
|
||||
|
||||
Flags<ReportIS::StreamType>
|
||||
LogTriggerConf::getStreams(SecurityType security_type, bool is_action_drop_or_prevent) const
|
||||
{
|
||||
if (is_action_drop_or_prevent && should_log_on_prevent.isSet(security_type)) return active_streams;
|
||||
if (!is_action_drop_or_prevent && should_log_on_detect.isSet(security_type)) return active_streams;
|
||||
|
||||
return Flags<ReportIS::StreamType>();
|
||||
}
|
||||
|
||||
Flags<ReportIS::Enreachments>
|
||||
LogTriggerConf::getEnrechments(SecurityType security_type) const
|
||||
{
|
||||
Flags<ReportIS::Enreachments> enreachments;
|
||||
|
||||
if (log_geo_location.isSet(security_type)) enreachments.setFlag(ReportIS::Enreachments::GEOLOCATION);
|
||||
if (should_format_output) enreachments.setFlag(ReportIS::Enreachments::BEAUTIFY_OUTPUT);
|
||||
|
||||
return enreachments;
|
||||
}
|
||||
|
||||
template <typename EnumClass>
|
||||
static void
|
||||
setTriggersFlag(const string &key, cereal::JSONInputArchive &ar, EnumClass flag, Flags<EnumClass> &flags)
|
||||
{
|
||||
bool value = false;
|
||||
parseJSONKey<bool>(key, value, ar);
|
||||
if (value) flags.setFlag(flag);
|
||||
}
|
||||
|
||||
static void
|
||||
setLogConfiguration(
|
||||
const ReportIS::StreamType &log_type,
|
||||
const string &log_server_url = "",
|
||||
const string &protocol = ""
|
||||
)
|
||||
{
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "log server url:" << log_server_url;
|
||||
if (log_server_url != "" && protocol != "") {
|
||||
Singleton::Consume<I_Logging>::by<LogTriggerConf>()->addStream(log_type, log_server_url, protocol);
|
||||
} else {
|
||||
Singleton::Consume<I_Logging>::by<LogTriggerConf>()->addStream(log_type);
|
||||
}
|
||||
}
|
||||
|
||||
static string
|
||||
parseProtocolWithDefault(
|
||||
const std::string &default_value,
|
||||
const std::string &key_name,
|
||||
cereal::JSONInputArchive &archive_in
|
||||
)
|
||||
{
|
||||
string value;
|
||||
try {
|
||||
archive_in(cereal::make_nvp(key_name, value));
|
||||
} catch (const cereal::Exception &e) {
|
||||
return default_value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void
|
||||
LogTriggerConf::load(cereal::JSONInputArchive& archive_in)
|
||||
{
|
||||
try {
|
||||
parseJSONKey<string>("triggerName", name, archive_in);
|
||||
parseJSONKey<string>("verbosity", verbosity, archive_in);
|
||||
parseJSONKey<string>("urlForSyslog", url_for_syslog, archive_in);
|
||||
parseJSONKey<string>("urlForCef", url_for_cef, archive_in);
|
||||
parseJSONKey<string>("syslogProtocol", syslog_protocol, archive_in);
|
||||
syslog_protocol = parseProtocolWithDefault("UDP", "syslogProtocol", archive_in);
|
||||
cef_protocol = parseProtocolWithDefault("UDP", "cefProtocol", archive_in);
|
||||
|
||||
setTriggersFlag("webBody", archive_in, WebLogFields::webBody, log_web_fields);
|
||||
setTriggersFlag("webHeaders", archive_in, WebLogFields::webHeaders, log_web_fields);
|
||||
setTriggersFlag("webRequests", archive_in, WebLogFields::webRequests, log_web_fields);
|
||||
setTriggersFlag("webUrlPath", archive_in, WebLogFields::webUrlPath, log_web_fields);
|
||||
setTriggersFlag("webUrlQuery", archive_in, WebLogFields::webUrlQuery, log_web_fields);
|
||||
setTriggersFlag("logToAgent", archive_in, ReportIS::StreamType::JSON_LOG_FILE, active_streams);
|
||||
setTriggersFlag("logToCloud", archive_in, ReportIS::StreamType::JSON_FOG, active_streams);
|
||||
setTriggersFlag("logToK8sService", archive_in, ReportIS::StreamType::JSON_K8S_SVC, active_streams);
|
||||
setTriggersFlag("logToSyslog", archive_in, ReportIS::StreamType::SYSLOG, active_streams);
|
||||
setTriggersFlag("logToCef", archive_in, ReportIS::StreamType::CEF, active_streams);
|
||||
setTriggersFlag("acAllow", archive_in, SecurityType::AccessControl, should_log_on_detect);
|
||||
setTriggersFlag("acDrop", archive_in, SecurityType::AccessControl, should_log_on_prevent);
|
||||
setTriggersFlag("tpDetect", archive_in, SecurityType::ThreatPrevention, should_log_on_detect);
|
||||
setTriggersFlag("tpPrevent", archive_in, SecurityType::ThreatPrevention, should_log_on_prevent);
|
||||
setTriggersFlag("complianceWarnings", archive_in, SecurityType::Compliance, should_log_on_detect);
|
||||
setTriggersFlag("complianceViolations", archive_in, SecurityType::Compliance, should_log_on_prevent);
|
||||
setTriggersFlag("acLogGeoLocation", archive_in, SecurityType::AccessControl, log_geo_location);
|
||||
setTriggersFlag("tpLogGeoLocation", archive_in, SecurityType::ThreatPrevention, log_geo_location);
|
||||
setTriggersFlag("complianceLogGeoLocation", archive_in, SecurityType::Compliance, log_geo_location);
|
||||
|
||||
bool extend_logging = false;
|
||||
parseJSONKey<bool>("extendLogging", extend_logging, archive_in);
|
||||
if (extend_logging) {
|
||||
setTriggersFlag("responseCode", archive_in, WebLogFields::responseCode, log_web_fields);
|
||||
setTriggersFlag("responseBody", archive_in, WebLogFields::responseBody, log_web_fields);
|
||||
|
||||
string severity;
|
||||
static const map<string, extendLoggingSeverity> extend_logging_severity_strings = {
|
||||
{"High", extendLoggingSeverity::High},
|
||||
{"Critical", extendLoggingSeverity::Critical}
|
||||
};
|
||||
parseJSONKey<string>("extendLoggingMinSeverity", severity, archive_in);
|
||||
auto extended_severity = extend_logging_severity_strings.find(severity);
|
||||
if (extended_severity != extend_logging_severity_strings.end()) {
|
||||
extend_logging_severity = extended_severity->second;
|
||||
} else {
|
||||
dbgWarning(D_RULEBASE_CONFIG)
|
||||
<< "Failed to parse the extendLoggingMinSeverityfield: '"
|
||||
<< severity
|
||||
<< "'";
|
||||
}
|
||||
}
|
||||
|
||||
for (ReportIS::StreamType log_stream : makeRange<ReportIS::StreamType>()) {
|
||||
if (!active_streams.isSet(log_stream)) continue;
|
||||
switch (log_stream) {
|
||||
case ReportIS::StreamType::JSON_DEBUG:
|
||||
setLogConfiguration(ReportIS::StreamType::JSON_DEBUG);
|
||||
break;
|
||||
case ReportIS::StreamType::JSON_FOG:
|
||||
setLogConfiguration(ReportIS::StreamType::JSON_FOG);
|
||||
break;
|
||||
case ReportIS::StreamType::JSON_LOG_FILE:
|
||||
setLogConfiguration(ReportIS::StreamType::JSON_LOG_FILE);
|
||||
break;
|
||||
case ReportIS::StreamType::JSON_K8S_SVC:
|
||||
setLogConfiguration(ReportIS::StreamType::JSON_K8S_SVC);
|
||||
break;
|
||||
case ReportIS::StreamType::SYSLOG:
|
||||
setLogConfiguration(ReportIS::StreamType::SYSLOG, getUrlForSyslog(), syslog_protocol);
|
||||
break;
|
||||
case ReportIS::StreamType::CEF:
|
||||
setLogConfiguration(ReportIS::StreamType::CEF, getUrlForCef(), cef_protocol);
|
||||
break;
|
||||
case ReportIS::StreamType::NONE: break;
|
||||
case ReportIS::StreamType::COUNT: break;
|
||||
}
|
||||
}
|
||||
|
||||
parseJSONKey<bool>("formatLoggingOutput", should_format_output, archive_in);
|
||||
} catch (const exception &e) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to parse the log trigger configuration: '" << e.what() << "'";
|
||||
archive_in.setNextName(nullptr);
|
||||
}
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
// 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 "generic_rulebase/zone.h"
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const unordered_map<string, Zone::Direction> string_to_direction = {
|
||||
{ "to", Zone::Direction::To },
|
||||
{ "from", Zone::Direction::From },
|
||||
{ "bidirectional", Zone::Direction::Bidirectional }
|
||||
};
|
||||
|
||||
class AdjacentZone
|
||||
{
|
||||
public:
|
||||
void
|
||||
load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
string direction_as_string;
|
||||
archive_in(cereal::make_nvp("direction", direction_as_string));
|
||||
archive_in(cereal::make_nvp("zoneId", id));
|
||||
auto maybe_direction = string_to_direction.find(direction_as_string);
|
||||
if (maybe_direction == string_to_direction.end()) {
|
||||
reportConfigurationError(
|
||||
"Illegal direction provided for adjacency. Provided direction in configuration: " +
|
||||
direction_as_string
|
||||
);
|
||||
}
|
||||
dir = maybe_direction->second;
|
||||
}
|
||||
|
||||
pair<Zone::Direction, GenericConfigId> getValue() const { return make_pair(dir, id); }
|
||||
|
||||
private:
|
||||
Zone::Direction dir;
|
||||
GenericConfigId id;
|
||||
};
|
||||
|
||||
class TagsValues
|
||||
{
|
||||
public:
|
||||
static const string req_attrs_ctx_key;
|
||||
|
||||
TagsValues() {}
|
||||
|
||||
template <typename Archive>
|
||||
void
|
||||
serialize(Archive &ar)
|
||||
{
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<Zone>();
|
||||
auto req_attrs = env->get<set<string>>(req_attrs_ctx_key);
|
||||
if (!req_attrs.ok()) return;
|
||||
|
||||
for (const string &req_attr : *req_attrs) {
|
||||
try {
|
||||
string data;
|
||||
ar(cereal::make_nvp(req_attr, data));
|
||||
dbgDebug(D_RULEBASE_CONFIG)
|
||||
<< "Found value for requested attribute. Tag: "
|
||||
<< req_attr
|
||||
<< ", Value: "
|
||||
<< data;
|
||||
|
||||
tags_set[req_attr].insert(data);
|
||||
} catch (const exception &e) {
|
||||
dbgDebug(D_RULEBASE_CONFIG) << "Could not find values for requested attribute. Tag: " << req_attr;
|
||||
ar.setNextName(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
matchValueByKey(const string &requested_key, const unordered_set<string> &possible_values) const
|
||||
{
|
||||
auto values = tags_set.find(requested_key);
|
||||
if (values == tags_set.end()) return false;
|
||||
|
||||
for (const string &val : possible_values) {
|
||||
if (values->second.count(val)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
insert(const TagsValues &other)
|
||||
{
|
||||
for (auto &single_tags_value : other.getData()) {
|
||||
tags_set[single_tags_value.first].insert(single_tags_value.second.begin(), single_tags_value.second.end());
|
||||
}
|
||||
}
|
||||
|
||||
const unordered_map<string, set<string>> & getData() const { return tags_set; }
|
||||
|
||||
private:
|
||||
unordered_map<string, set<string>> tags_set;
|
||||
};
|
||||
|
||||
const string TagsValues::req_attrs_ctx_key = "requested attributes key";
|
||||
|
||||
void
|
||||
Zone::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
archive_in(cereal::make_nvp("id", zone_id));
|
||||
archive_in(cereal::make_nvp("name", zone_name));
|
||||
vector<AdjacentZone> adjacency;
|
||||
try {
|
||||
archive_in(cereal::make_nvp("adjacentZones", adjacency));
|
||||
} catch (const cereal::Exception &) {
|
||||
dbgTrace(D_RULEBASE_CONFIG)
|
||||
<< "List of adjacentZones does not exist for current object. Zone id: "
|
||||
<< zone_id
|
||||
<< ", Zone name: "
|
||||
<< zone_name;
|
||||
|
||||
archive_in.setNextName(nullptr);
|
||||
}
|
||||
|
||||
for (const AdjacentZone &zone : adjacency) {
|
||||
adjacent_zones.push_back(zone.getValue());
|
||||
}
|
||||
|
||||
archive_in(cereal::make_nvp("match", match_query));
|
||||
|
||||
is_any =
|
||||
match_query.getType() == MatchQuery::MatchType::Condition &&
|
||||
match_query.getKey() == "any" &&
|
||||
match_query.getValue().count("any") > 0;
|
||||
|
||||
set<string> keys = match_query.getAllKeys();
|
||||
}
|
||||
|
||||
const string
|
||||
contextKeyToString(Context::MetaDataType type)
|
||||
{
|
||||
if (type == Context::MetaDataType::SubjectIpAddr || type == Context::MetaDataType::OtherIpAddr) return "ip";
|
||||
return Context::convertToString(type);
|
||||
}
|
||||
|
||||
bool
|
||||
Zone::contains(const Asset &asset)
|
||||
{
|
||||
QueryRequest request;
|
||||
|
||||
for (const auto &main_attr : asset.getAttrs()) {
|
||||
request.addCondition(Condition::EQUALS, contextKeyToString(main_attr.first), main_attr.second);
|
||||
}
|
||||
|
||||
ScopedContext req_attrs_key;
|
||||
req_attrs_key.registerValue<set<string>>(TagsValues::req_attrs_ctx_key, match_query.getAllKeys());
|
||||
|
||||
I_Intelligence_IS_V2 *intelligence = Singleton::Consume<I_Intelligence_IS_V2>::by<Zone>();
|
||||
auto query_res = intelligence->queryIntelligence<TagsValues>(request);
|
||||
if (!query_res.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to perform intelligence query. Error: " << query_res.getErr();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const AssetReply<TagsValues> &asset : query_res.unpack()) {
|
||||
TagsValues tag_values = asset.mergeReplyData();
|
||||
|
||||
if (match_query.matchAttributes(tag_values.getData())) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
// 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 "generic_rulebase/zones_config.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "generic_rulebase/generic_rulebase_utils.h"
|
||||
#include "config.h"
|
||||
#include "ip_utilities.h"
|
||||
#include "connkey.h"
|
||||
#include "i_generic_rulebase.h"
|
||||
|
||||
USE_DEBUG_FLAG(D_RULEBASE_CONFIG);
|
||||
|
||||
using namespace std;
|
||||
|
||||
void
|
||||
ZonesConfig::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgFlow(D_RULEBASE_CONFIG) << "Saving active zones";
|
||||
set<string> used_zones;
|
||||
cereal::load(archive_in, used_zones);
|
||||
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Loading all zones";
|
||||
auto all_zones_maybe = getSetting<Zones>("rulebase", "zones");
|
||||
if (!all_zones_maybe.ok()) {
|
||||
dbgWarning(D_RULEBASE_CONFIG) << "Failed to load zones";
|
||||
return;
|
||||
}
|
||||
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Creating cache of all zones by ID";
|
||||
map<GenericConfigId, Zone> all_zones;
|
||||
for (const auto &single_zone : all_zones_maybe.unpack().zones) {
|
||||
if (used_zones.count(single_zone.getId()) > 0 && single_zone.isAnyZone()) {
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Found used zone of type \"Any\": saving all zones as active zones";
|
||||
zones = all_zones_maybe.unpack().zones;
|
||||
return;
|
||||
}
|
||||
|
||||
dbgDebug(D_RULEBASE_CONFIG)
|
||||
<< "Adding specific zone to cache. Zone ID: "
|
||||
<< single_zone.getId()
|
||||
<< ", name: "
|
||||
<< single_zone.getName();
|
||||
all_zones.emplace(single_zone.getId(), single_zone);
|
||||
}
|
||||
|
||||
dbgTrace(D_RULEBASE_CONFIG) << "Creating list of active zones";
|
||||
map<GenericConfigId, Zone> active_zones_set;
|
||||
for (const auto &single_used_zone_id : used_zones) {
|
||||
const auto &found_zone = all_zones[single_used_zone_id];
|
||||
dbgTrace(D_RULEBASE_CONFIG)
|
||||
<< "Adding zone to list of active zones. Zone ID: "
|
||||
<< single_used_zone_id
|
||||
<< ", zone name: "
|
||||
<< found_zone.getName();
|
||||
active_zones_set.emplace(found_zone.getId(), found_zone);
|
||||
|
||||
for (const auto &adjacent_zone : found_zone.getAdjacentZones()) {
|
||||
const auto &adjacent_zone_obj = all_zones[adjacent_zone.second];
|
||||
dbgTrace(D_RULEBASE_CONFIG)
|
||||
<< "Adding adjacent zone to list of active zones. Zone ID: "
|
||||
<< adjacent_zone_obj.getId()
|
||||
<< ", zone name: "
|
||||
<< adjacent_zone_obj.getName();
|
||||
active_zones_set.emplace(adjacent_zone_obj.getId(), adjacent_zone_obj);
|
||||
}
|
||||
}
|
||||
|
||||
vector<GenericConfigId> implied_zones = {
|
||||
"impliedAzure",
|
||||
"impliedDNS",
|
||||
"impliedSSH",
|
||||
"impliedProxy",
|
||||
"impliedFog"
|
||||
};
|
||||
|
||||
GenericConfigId any_zone_id = "";
|
||||
for (const auto &single_zone : all_zones_maybe.unpack().zones) {
|
||||
if (single_zone.isAnyZone()) any_zone_id = single_zone.getId();
|
||||
}
|
||||
for (GenericConfigId &implied_id: implied_zones) {
|
||||
if (all_zones.find(implied_id) != all_zones.end()) {
|
||||
dbgDebug(D_RULEBASE_CONFIG) << "Adding implied zone to cache. Zone ID: " << implied_id;
|
||||
active_zones_set.emplace(implied_id, all_zones[implied_id]);
|
||||
if (any_zone_id != "" && active_zones_set.count(any_zone_id) == 0) {
|
||||
active_zones_set.emplace(any_zone_id, all_zones[any_zone_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &single_id_zone_pair : active_zones_set) {
|
||||
zones.push_back(single_id_zone_pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ZonesConfig::preload()
|
||||
{
|
||||
registerExpectedSetting<Zones>("rulebase", "zones");
|
||||
registerExpectedSetting<ZonesConfig>("rulebase", "usedZones");
|
||||
}
|
@ -34,6 +34,7 @@ public:
|
||||
~DetailsResolver();
|
||||
|
||||
void preload() override;
|
||||
void init() override;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "url_parser.h"
|
||||
#include "i_agent_details.h"
|
||||
#include "i_mainloop.h"
|
||||
#include "i_environment.h"
|
||||
#include "singleton.h"
|
||||
#include "component.h"
|
||||
|
||||
@ -32,6 +33,7 @@ class Downloader
|
||||
Singleton::Consume<I_Encryptor>,
|
||||
Singleton::Consume<I_MainLoop>,
|
||||
Singleton::Consume<I_OrchestrationTools>,
|
||||
Singleton::Consume<I_Environment>,
|
||||
Singleton::Consume<I_UpdateCommunication>
|
||||
{
|
||||
public:
|
||||
|
@ -117,7 +117,7 @@ public:
|
||||
const std::string &conf_path) const = 0;
|
||||
virtual bool copyFile(const std::string &src_path, const std::string &dst_path) const = 0;
|
||||
virtual bool doesFileExist(const std::string &file_path) const = 0;
|
||||
virtual void getClusterId() const = 0;
|
||||
virtual void setClusterId() const = 0;
|
||||
virtual void fillKeyInJson(
|
||||
const std::string &filename,
|
||||
const std::string &_key,
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
~OrchestrationStatus();
|
||||
|
||||
void init() override;
|
||||
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> pimpl;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "i_package_handler.h"
|
||||
#include "i_orchestration_tools.h"
|
||||
#include "i_shell_cmd.h"
|
||||
#include "i_environment.h"
|
||||
#include "component.h"
|
||||
|
||||
class PackageHandler
|
||||
@ -24,7 +25,8 @@ class PackageHandler
|
||||
public Component,
|
||||
Singleton::Provide<I_PackageHandler>,
|
||||
Singleton::Consume<I_ShellCmd>,
|
||||
Singleton::Consume<I_OrchestrationTools>
|
||||
Singleton::Consume<I_OrchestrationTools>,
|
||||
Singleton::Consume<I_Environment>
|
||||
{
|
||||
public:
|
||||
PackageHandler();
|
||||
|
@ -35,8 +35,10 @@ public:
|
||||
bool isOverSSL() const { return over_ssl; }
|
||||
std::string getPort() const { return port; }
|
||||
std::string getQuery() const { return query; }
|
||||
std::string getHost() const;
|
||||
URLProtocol getProtocol() const { return protocol; }
|
||||
std::string toString() const;
|
||||
void setHost(const std::string &new_host);
|
||||
void setQuery(const std::string &new_query);
|
||||
|
||||
private:
|
||||
@ -47,6 +49,7 @@ private:
|
||||
std::string base_url;
|
||||
std::string port;
|
||||
std::string query;
|
||||
std::string host;
|
||||
URLProtocol protocol;
|
||||
};
|
||||
|
||||
|
@ -50,9 +50,13 @@ public:
|
||||
|
||||
private:
|
||||
void readRules(cereal::JSONInputArchive &ar);
|
||||
void readTriggerId(cereal::JSONInputArchive &ar);
|
||||
void readExceptionId(cereal::JSONInputArchive &ar);
|
||||
void readDefaultAction(cereal::JSONInputArchive &ar);
|
||||
|
||||
std::vector<Rule> rules;
|
||||
std::string trigger_id;
|
||||
std::string exception_id;
|
||||
};
|
||||
|
||||
#endif // __IPS_BASIC_POLICY_H__
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "log_generator.h"
|
||||
#include "parsed_context.h"
|
||||
#include "pm_hook.h"
|
||||
#include "i_generic_rulebase.h"
|
||||
|
||||
/// \namespace IPSSignatureSubTypes
|
||||
/// \brief Namespace containing subtypes for IPS signatures.
|
||||
@ -348,8 +349,16 @@ public:
|
||||
/// \brief Construct a SignatureAndAction object.
|
||||
/// \param _signature The complete signature.
|
||||
/// \param _action The signature action.
|
||||
SignatureAndAction(std::shared_ptr<CompleteSignature> _signature, SignatureAction _action) :
|
||||
signature(_signature), action(_action)
|
||||
SignatureAndAction(
|
||||
std::shared_ptr<CompleteSignature> _signature,
|
||||
SignatureAction _action,
|
||||
std::string _trigger_id,
|
||||
std::string _exception_id)
|
||||
:
|
||||
signature(_signature),
|
||||
action(_action),
|
||||
trigger_id(_trigger_id),
|
||||
exception_id(_exception_id)
|
||||
{}
|
||||
|
||||
/// \brief Check if the signature is matched for prevention.
|
||||
@ -375,6 +384,11 @@ public:
|
||||
return signature->getContext();
|
||||
}
|
||||
|
||||
LogTriggerConf getTrigger() const;
|
||||
|
||||
std::set<ParameterBehavior>
|
||||
getBehavior(const std::unordered_map<std::string, std::set<std::string>> &exceptions_dict) const;
|
||||
|
||||
private:
|
||||
/// \brief Get the action results for the IPS state.
|
||||
/// \param ips_state The IPS entry.
|
||||
@ -382,6 +396,8 @@ private:
|
||||
|
||||
std::shared_ptr<CompleteSignature> signature;
|
||||
SignatureAction action;
|
||||
std::string trigger_id;
|
||||
std::string exception_id;
|
||||
};
|
||||
} // namespace IPSSignatureSubTypes
|
||||
|
||||
|
@ -17,6 +17,8 @@ public:
|
||||
private:
|
||||
IPSSignatureSubTypes::SignatureAction action = IPSSignatureSubTypes::SignatureAction::IGNORE;
|
||||
std::vector<std::string> file_names;
|
||||
std::string trigger_id;
|
||||
std::string exception_id;
|
||||
};
|
||||
|
||||
#endif // __SNORT_BASIC_POLICY_H__
|
||||
|
@ -17,6 +17,8 @@ void
|
||||
RuleSelector::load(cereal::JSONInputArchive &ar)
|
||||
{
|
||||
readRules(ar);
|
||||
readTriggerId(ar);
|
||||
readExceptionId(ar);
|
||||
readDefaultAction(ar);
|
||||
}
|
||||
|
||||
@ -36,7 +38,7 @@ RuleSelector::selectSignatures() const
|
||||
if (rule.isSignaturedMatched(*signature)) {
|
||||
if (rule.getAction() != IPSSignatureSubTypes::SignatureAction::IGNORE) {
|
||||
signature->setIndicators("Check Point", signatures_version);
|
||||
res.emplace_back(signature, rule.getAction());
|
||||
res.emplace_back(signature, rule.getAction(), trigger_id, exception_id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -52,6 +54,28 @@ RuleSelector::readRules(cereal::JSONInputArchive &ar)
|
||||
ar(cereal::make_nvp("rules", rules));
|
||||
}
|
||||
|
||||
void
|
||||
RuleSelector::readTriggerId(cereal::JSONInputArchive &ar)
|
||||
{
|
||||
try {
|
||||
ar(cereal::make_nvp("triggers", trigger_id));
|
||||
} catch (const cereal::Exception &e) {
|
||||
ar.setNextName(nullptr);
|
||||
trigger_id = "";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RuleSelector::readExceptionId(cereal::JSONInputArchive &ar)
|
||||
{
|
||||
try {
|
||||
ar(cereal::make_nvp("exceptions", exception_id));
|
||||
} catch (const cereal::Exception &e) {
|
||||
ar.setNextName(nullptr);
|
||||
exception_id = "";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RuleSelector::readDefaultAction(cereal::JSONInputArchive &ar)
|
||||
{
|
||||
|
@ -280,8 +280,7 @@ SignatureAndAction::getAction(const IPSEntry &ips_state) const
|
||||
exceptions_dict["sourceIdentifier"].insert(*env_source_identifier);
|
||||
}
|
||||
|
||||
I_GenericRulebase *i_rulebase = Singleton::Consume<I_GenericRulebase>::by<IPSComp>();
|
||||
auto behaviors = i_rulebase->getBehavior(exceptions_dict);
|
||||
auto behaviors = getBehavior(exceptions_dict);
|
||||
|
||||
set<BehaviorValue> override_actions;
|
||||
vector<string> override_ids;
|
||||
@ -315,6 +314,23 @@ static const auto url_query = LogTriggerConf::WebLogFields::webUrlQuery;
|
||||
static const auto res_body = LogTriggerConf::WebLogFields::responseBody;
|
||||
static const auto res_code = LogTriggerConf::WebLogFields::responseCode;
|
||||
|
||||
LogTriggerConf
|
||||
SignatureAndAction::getTrigger() const
|
||||
{
|
||||
if (trigger_id.empty()) return getConfigurationWithDefault(LogTriggerConf(), "rulebase", "log");
|
||||
|
||||
return Singleton::Consume<I_GenericRulebase>::by<IPSComp>()->getLogTriggerConf(trigger_id);
|
||||
}
|
||||
|
||||
set<ParameterBehavior>
|
||||
SignatureAndAction::getBehavior(const unordered_map<string, set<string>> &exceptions_dict) const
|
||||
{
|
||||
I_GenericRulebase *i_rulebase = Singleton::Consume<I_GenericRulebase>::by<IPSComp>();
|
||||
if (exception_id.empty()) return i_rulebase->getBehavior(exceptions_dict);
|
||||
|
||||
return i_rulebase->getParameterException(exception_id).getBehavior(exceptions_dict);
|
||||
}
|
||||
|
||||
bool
|
||||
SignatureAndAction::matchSilent(const Buffer &sample) const
|
||||
{
|
||||
@ -398,7 +414,7 @@ SignatureAndAction::isMatchedPrevent(const Buffer &context_buffer, const set<PMP
|
||||
|
||||
dbgDebug(D_IPS) << "Signature matched - sending log";
|
||||
|
||||
auto &trigger = getConfigurationWithDefault(default_triger, "rulebase", "log");
|
||||
auto trigger = getTrigger();
|
||||
bool is_prevent = get<0>(override_action) == IPSSignatureSubTypes::SignatureAction::PREVENT;
|
||||
|
||||
auto severity = signature->getSeverity() < IPSLevel::HIGH ? Severity::HIGH : Severity::CRITICAL;
|
||||
|
@ -596,6 +596,8 @@ TEST_F(ComponentTest, check_filtering_by_year)
|
||||
|
||||
TEST_F(ComponentTest, log_fields)
|
||||
{
|
||||
generic_rulebase.preload();
|
||||
generic_rulebase.init();
|
||||
string config =
|
||||
"{"
|
||||
"\"IPS\": {"
|
||||
@ -632,6 +634,8 @@ TEST_F(ComponentTest, log_fields)
|
||||
"\"assetId\": \"1-1-1\","
|
||||
"\"practiceId\": \"2-2-2\","
|
||||
"\"practiceName\": \"practice1\","
|
||||
"\"triggers\": \"5eaeefde6765c30010bae8b6\","
|
||||
"\"exceptions\": \"\","
|
||||
"\"defaultAction\": \"Detect\","
|
||||
"\"rules\": ["
|
||||
"{"
|
||||
@ -643,10 +647,36 @@ TEST_F(ComponentTest, log_fields)
|
||||
"]"
|
||||
"}"
|
||||
"]"
|
||||
"},"
|
||||
"\"rulebase\": {"
|
||||
"\"log\": ["
|
||||
"{"
|
||||
"\"context\": \"triggerId(5eaeefde6765c30010bae8b6)\","
|
||||
"\"triggerName\": \"Logging Trigger\","
|
||||
"\"triggerType\": \"log\","
|
||||
"\"urlForSyslog\": \"\","
|
||||
"\"urlForCef\": \"128.1.1.1:333\","
|
||||
"\"acAllow\": false,"
|
||||
"\"acDrop\": true,"
|
||||
"\"complianceViolations\": true,"
|
||||
"\"complianceWarnings\": true,"
|
||||
"\"logToAgent\": true,"
|
||||
"\"logToCloud\": true,"
|
||||
"\"logToSyslog\": false,"
|
||||
"\"logToCef\": true,"
|
||||
"\"tpDetect\": true,"
|
||||
"\"tpPrevent\": true,"
|
||||
"\"verbosity\": \"Standard\","
|
||||
"\"webBody\": true,"
|
||||
"\"webHeaders\": true,"
|
||||
"\"webRequests\": true,"
|
||||
"\"webUrlPath\": true,"
|
||||
"\"webUrlQuery\": true"
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"}";
|
||||
loadPolicy(config);
|
||||
setTrigger();
|
||||
|
||||
EXPECT_CALL(table, createStateRValueRemoved(_, _));
|
||||
EXPECT_CALL(table, getState(_)).WillRepeatedly(Return(&entry));
|
||||
@ -829,6 +859,8 @@ TEST_F(ComponentTest, prxeem_exception_bug)
|
||||
" \"practiceId\": \"2-2-2\","
|
||||
" \"practiceName\": \"practice1\","
|
||||
" \"defaultAction\": \"Prevent\","
|
||||
" \"triggers\": \"\","
|
||||
" \"exceptions\": \"6c3867be-4da5-42c2-93dc-8f509a764004\","
|
||||
" \"rules\": []"
|
||||
" }"
|
||||
" ]"
|
||||
@ -847,6 +879,11 @@ TEST_F(ComponentTest, prxeem_exception_bug)
|
||||
" \"parameterId\": \"6c3867be-4da5-42c2-93dc-8f509a764003\","
|
||||
" \"parameterType\": \"exceptions\","
|
||||
" \"parameterName\": \"exception\""
|
||||
" },"
|
||||
" {"
|
||||
" \"parameterId\": \"6c3867be-4da5-42c2-93dc-8f509a764004\","
|
||||
" \"parameterType\": \"exceptions\","
|
||||
" \"parameterName\": \"exception\""
|
||||
" }"
|
||||
" ],"
|
||||
" \"zoneId\": \"\","
|
||||
@ -855,7 +892,7 @@ TEST_F(ComponentTest, prxeem_exception_bug)
|
||||
" ],"
|
||||
" \"exception\": ["
|
||||
" {"
|
||||
" \"context\": \"parameterId(6c3867be-4da5-42c2-93dc-8f509a764003)\","
|
||||
" \"context\": \"parameterId(6c3867be-4da5-42c2-93dc-8f509a764004)\","
|
||||
" \"match\": {"
|
||||
" \"type\": \"operator\","
|
||||
" \"op\": \"and\","
|
||||
|
@ -16,6 +16,19 @@ using namespace std;
|
||||
void
|
||||
SnortRuleSelector::load(cereal::JSONInputArchive &ar)
|
||||
{
|
||||
try {
|
||||
ar(cereal::make_nvp("triggers", trigger_id));
|
||||
} catch (const cereal::Exception &e) {
|
||||
ar.setNextName(nullptr);
|
||||
trigger_id = "";
|
||||
}
|
||||
|
||||
try {
|
||||
ar(cereal::make_nvp("exceptions", exception_id));
|
||||
} catch (const cereal::Exception &e) {
|
||||
ar.setNextName(nullptr);
|
||||
exception_id = "";
|
||||
}
|
||||
string mode;
|
||||
ar(cereal::make_nvp("mode", mode), cereal::make_nvp("files", file_names));
|
||||
|
||||
@ -38,7 +51,7 @@ SnortRuleSelector::selectSignatures() const
|
||||
|
||||
for (auto &file : file_names) {
|
||||
for (auto &signature : (*signatures).getSignatures(file)) {
|
||||
res.emplace_back(signature, action);
|
||||
res.emplace_back(signature, action, trigger_id, exception_id);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
@ -228,6 +228,7 @@ AccessControlPracticeSpec::load(cereal::JSONInputArchive &archive_in)
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice spec";
|
||||
|
||||
parseAppsecJSONKey<string>("name", practice_name, archive_in);
|
||||
parseAppsecJSONKey<string>("practiceMode", mode, archive_in);
|
||||
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
|
||||
parseMandatoryAppsecJSONKey<AccessControlRateLimit>("rateLimit", rate_limit, archive_in);
|
||||
}
|
||||
@ -255,4 +256,10 @@ AccessControlPracticeSpec::getName() const
|
||||
{
|
||||
return practice_name;
|
||||
}
|
||||
|
||||
const string &
|
||||
AccessControlPracticeSpec::getMode(const std::string &default_mode) const
|
||||
{
|
||||
return isModeInherited(mode) ? default_mode : mode;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
@ -181,12 +181,14 @@ public:
|
||||
const AccessControlRateLimit &getRateLimit() const;
|
||||
const std::string & getAppSecClassName() const;
|
||||
const std::string & getName() const;
|
||||
const std::string & getMode(const std::string &default_mode = "inactive") const;
|
||||
void setName(const std::string &_name);
|
||||
|
||||
private:
|
||||
AccessControlRateLimit rate_limit;
|
||||
std::string appsec_class_name;
|
||||
std::string practice_name;
|
||||
std::string mode;
|
||||
};
|
||||
|
||||
#endif // __ACCESS_CONTROL_PRACTICE_H__
|
||||
|
@ -587,6 +587,7 @@ public:
|
||||
const NewFileSecurity & getFileSecurity() const;
|
||||
const std::string & getAppSecClassName() const;
|
||||
const std::string & getName() const;
|
||||
const std::string & getMode(const std::string &default_mode = "inactive") const;
|
||||
void setName(const std::string &_name);
|
||||
|
||||
private:
|
||||
@ -598,6 +599,7 @@ private:
|
||||
NewAppSecPracticeAntiBot anti_bot;
|
||||
std::string appsec_class_name;
|
||||
std::string practice_name;
|
||||
std::string mode;
|
||||
};
|
||||
|
||||
#endif // __NEW_PRACTICE_H__
|
||||
|
@ -1025,6 +1025,7 @@ NewAppSecPracticeSpec::load(cereal::JSONInputArchive &archive_in)
|
||||
parseMandatoryAppsecJSONKey<NewAppSecPracticeWebAttacks>("webAttacks", web_attacks, archive_in);
|
||||
parseAppsecJSONKey<NewAppSecPracticeAntiBot>("antiBot", anti_bot, archive_in);
|
||||
parseAppsecJSONKey<string>("name", practice_name, archive_in);
|
||||
parseAppsecJSONKey<string>("practiceMode", mode, archive_in, "inherited");
|
||||
}
|
||||
|
||||
void
|
||||
@ -1080,4 +1081,11 @@ NewAppSecPracticeSpec::getName() const
|
||||
{
|
||||
return practice_name;
|
||||
}
|
||||
|
||||
const string &
|
||||
NewAppSecPracticeSpec::getMode(const string &default_mode) const
|
||||
{
|
||||
return isModeInherited(mode) ? default_mode : mode;
|
||||
}
|
||||
|
||||
// LCOV_EXCL_STOP
|
||||
|
@ -1002,8 +1002,9 @@ PolicyMakerUtils::createIpsSections(
|
||||
auto apssec_practice = getAppsecPracticeSpec<V1beta2AppsecLinuxPolicy, NewAppSecPracticeSpec>(
|
||||
rule_annotations[AnnotationTypes::PRACTICE],
|
||||
policy);
|
||||
const string &override_mode =
|
||||
apssec_practice.getIntrusionPrevention().getMode(apssec_practice.getMode(default_mode));
|
||||
|
||||
const string &override_mode = apssec_practice.getIntrusionPrevention().getMode(default_mode);
|
||||
if (override_mode == "Inactive" || override_mode == "Disabled") return;
|
||||
|
||||
IpsProtectionsSection ips_section = IpsProtectionsSection(
|
||||
@ -1076,8 +1077,9 @@ PolicyMakerUtils::createSnortSections(
|
||||
auto apssec_practice = getAppsecPracticeSpec<V1beta2AppsecLinuxPolicy, NewAppSecPracticeSpec>(
|
||||
rule_annotations[AnnotationTypes::PRACTICE],
|
||||
policy);
|
||||
const string &override_mode =
|
||||
apssec_practice.getSnortSignatures().getOverrideMode(apssec_practice.getMode(default_mode));
|
||||
|
||||
const string &override_mode = apssec_practice.getSnortSignatures().getOverrideMode(default_mode);
|
||||
if (override_mode == "Inactive" ||
|
||||
override_mode == "Disabled" ||
|
||||
apssec_practice.getSnortSignatures().getFiles().size() == 0) {
|
||||
@ -1129,7 +1131,7 @@ PolicyMakerUtils::createFileSecuritySections(
|
||||
asset_id,
|
||||
practice_name,
|
||||
practice_id,
|
||||
default_mode
|
||||
apssec_practice.getMode(default_mode)
|
||||
);
|
||||
|
||||
file_security[asset_name] = file_security_section;
|
||||
@ -1171,7 +1173,7 @@ PolicyMakerUtils::createRateLimitSection(
|
||||
asset_name,
|
||||
url,
|
||||
uri,
|
||||
access_control_practice.getRateLimit().getMode(default_mode),
|
||||
access_control_practice.getRateLimit().getMode(access_control_practice.getMode(default_mode)),
|
||||
practice_id,
|
||||
rule_annotations[AnnotationTypes::ACCESS_CONTROL_PRACTICE],
|
||||
rules
|
||||
@ -1191,6 +1193,8 @@ PolicyMakerUtils::createWebAppSection(
|
||||
rule_annotations[AnnotationTypes::PRACTICE],
|
||||
policy
|
||||
);
|
||||
const string &practice_mode = apssec_practice.getMode(default_mode);
|
||||
|
||||
PracticeAdvancedConfig practice_advance_config(
|
||||
apssec_practice.getWebAttacks().getMaxHeaderSizeBytes(),
|
||||
apssec_practice.getWebAttacks().getMaxBodySizeKb(),
|
||||
@ -1206,8 +1210,8 @@ PolicyMakerUtils::createWebAppSection(
|
||||
practice_id,
|
||||
rule_annotations[AnnotationTypes::PRACTICE],
|
||||
rule_config.getContext(),
|
||||
apssec_practice.getWebAttacks().getMinimumConfidence(default_mode),
|
||||
apssec_practice.getWebAttacks().getMode(default_mode),
|
||||
apssec_practice.getWebAttacks().getMinimumConfidence(practice_mode),
|
||||
apssec_practice.getWebAttacks().getMode(practice_mode),
|
||||
practice_advance_config,
|
||||
apssec_practice.getAntiBot(),
|
||||
log_triggers[rule_annotations[AnnotationTypes::TRIGGER]],
|
||||
|
@ -32,6 +32,7 @@ class DetailsResolver::Impl
|
||||
Singleton::Provide<I_DetailsResolver>::From<DetailsResolver>
|
||||
{
|
||||
public:
|
||||
void init() { handler.init(); }
|
||||
Maybe<string> getHostname() override;
|
||||
Maybe<string> getPlatform() override;
|
||||
Maybe<string> getArch() override;
|
||||
@ -290,6 +291,12 @@ DetailsResolver::DetailsResolver() : Component("DetailsResolver"), pimpl(make_un
|
||||
|
||||
DetailsResolver::~DetailsResolver() {}
|
||||
|
||||
void
|
||||
DetailsResolver::init()
|
||||
{
|
||||
pimpl->init();
|
||||
}
|
||||
|
||||
void
|
||||
DetailsResolver::preload()
|
||||
{
|
||||
|
@ -223,7 +223,7 @@ FILE_CONTENT_HANDLER(
|
||||
FILE_CONTENT_HANDLER("os_release", "/etc/os-release", getOsRelease)
|
||||
#endif // gaia || smb
|
||||
|
||||
FILE_CONTENT_HANDLER("AppSecModelVersion", "/etc/cp/conf/waap/waap.data", getWaapModelVersion)
|
||||
FILE_CONTENT_HANDLER("AppSecModelVersion", "<FILESYSTEM-PREFIX>/conf/waap/waap.data", getWaapModelVersion)
|
||||
|
||||
#endif // FILE_CONTENT_HANDLER
|
||||
|
||||
|
@ -36,9 +36,12 @@ using FileContentHandler = function<Maybe<string>(shared_ptr<istream> file_otput
|
||||
|
||||
#include "checkpoint_product_handlers.h"
|
||||
|
||||
static const string filesystem_place_holder = "<FILESYSTEM-PREFIX>";
|
||||
|
||||
class DetailsResolvingHanlder::Impl
|
||||
{
|
||||
public:
|
||||
void init();
|
||||
map<string, string> getResolvedDetails() const;
|
||||
static Maybe<string> getCommandOutput(const string &cmd);
|
||||
|
||||
@ -70,6 +73,20 @@ private:
|
||||
};
|
||||
#undef SHELL_POST_CMD
|
||||
|
||||
void
|
||||
DetailsResolvingHanlder::Impl::init()
|
||||
{
|
||||
string actual_filesystem_prefix = getFilesystemPathConfig();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map<string, string>
|
||||
DetailsResolvingHanlder::Impl::getResolvedDetails() const
|
||||
{
|
||||
@ -155,6 +172,12 @@ DetailsResolvingHanlder::Impl::getCommandOutput(const string &cmd)
|
||||
DetailsResolvingHanlder::DetailsResolvingHanlder() : pimpl(make_unique<Impl>()) {}
|
||||
DetailsResolvingHanlder::~DetailsResolvingHanlder() {}
|
||||
|
||||
void
|
||||
DetailsResolvingHanlder::init()
|
||||
{
|
||||
return pimpl->init();
|
||||
}
|
||||
|
||||
map<string, string>
|
||||
DetailsResolvingHanlder::getResolvedDetails() const
|
||||
{
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
DetailsResolvingHanlder();
|
||||
~DetailsResolvingHanlder();
|
||||
|
||||
void init();
|
||||
std::map<std::string, std::string> getResolvedDetails() const;
|
||||
|
||||
static Maybe<std::string> getCommandOutput(const std::string &cmd);
|
||||
|
@ -1,5 +1,5 @@
|
||||
ADD_DEFINITIONS(-Wno-deprecated-declarations -Dalpine)
|
||||
|
||||
add_library(orchestration_downloader curl_client.cc downloader.cc http_client.cc https_client.cc)
|
||||
add_library(orchestration_downloader curl_client.cc downloader.cc http_client.cc https_client.cc https_client_helper.cc)
|
||||
|
||||
#add_subdirectory(downloader_ut)
|
||||
|
@ -121,6 +121,11 @@ Downloader::Impl::init()
|
||||
"Default file download path"
|
||||
);
|
||||
|
||||
auto maybe_vs_id = Singleton::Consume<I_Environment>::by<Downloader>()->get<string>("VS ID");
|
||||
if (maybe_vs_id.ok()) {
|
||||
dir_path = dir_path + "/vs" + maybe_vs_id.unpack();
|
||||
}
|
||||
|
||||
Singleton::Consume<I_OrchestrationTools>::by<Downloader>()->createDirectory(dir_path);
|
||||
}
|
||||
|
||||
|
@ -189,14 +189,12 @@ HTTPClient::getFile(const URLParser &url, ofstream &out_file, bool auth_required
|
||||
}
|
||||
|
||||
if (url.isOverSSL()) {
|
||||
auto get_file_over_ssl_res = getFileSSL(url, out_file, token);
|
||||
if (!get_file_over_ssl_res.ok())
|
||||
{
|
||||
//CURL fallback
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to get file over SSL. Trying via CURL (SSL).";
|
||||
return curlGetFileOverSSL(url, out_file, token);
|
||||
}
|
||||
return get_file_over_ssl_res;
|
||||
if (getFileSSLDirect(url, out_file, token).ok()) return Maybe<void>();
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to get file over SSL directly. Trying indirectly.";
|
||||
if (getFileSSL(url, out_file, token).ok()) return Maybe<void>();
|
||||
//CURL fallback
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to get file over SSL. Trying via CURL (SSL).";
|
||||
return curlGetFileOverSSL(url, out_file, token);
|
||||
}
|
||||
auto get_file_http_res = getFileHttp(url, out_file, token);
|
||||
if (!get_file_http_res.ok())
|
||||
|
@ -34,6 +34,7 @@ public:
|
||||
private:
|
||||
std::string loadCAChainDir();
|
||||
Maybe<void> getFileSSL(const URLParser &url, std::ofstream &out_file, const std::string &_token);
|
||||
Maybe<void> getFileSSLDirect(const URLParser &url, std::ofstream &out_file, const std::string &_token);
|
||||
Maybe<void> getFileHttp(const URLParser &url, std::ofstream &out_file, const std::string &_token);
|
||||
Maybe<void> curlGetFileOverHttp(const URLParser &url, std::ofstream &out_file, const std::string &_token);
|
||||
Maybe<void> curlGetFileOverSSL(const URLParser &url, std::ofstream &out_file, const std::string &_token);
|
||||
|
@ -90,7 +90,7 @@ public:
|
||||
ostream request_stream(&request_);
|
||||
stringstream http_request;
|
||||
http_request << "GET " << url.getQuery() << " HTTP/1.1\r\n";
|
||||
string host = url.getBaseURL().unpack();
|
||||
string host = url.getHost();
|
||||
string port = url.getPort();
|
||||
int port_int;
|
||||
try {
|
||||
|
@ -0,0 +1,20 @@
|
||||
// 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 "http_client.h"
|
||||
|
||||
Maybe<void>
|
||||
HTTPClient::getFileSSLDirect(const URLParser &, std::ofstream &, const std::string &)
|
||||
{
|
||||
return genError("No direct downloading in open-source");
|
||||
}
|
@ -47,6 +47,7 @@ HybridModeMetric::upon(const HybridModeMetricEvent &)
|
||||
string cmd_output = maybe_cmd_output.unpack();
|
||||
trim(cmd_output);
|
||||
dbgDebug(D_ORCHESTRATOR) << "Watchdog process counter: " << cmd_output;
|
||||
if (cmd_output.empty()) return;
|
||||
|
||||
try {
|
||||
wd_process_restart.report(stoi(cmd_output));
|
||||
|
@ -26,7 +26,7 @@ class NamespaceData : public ClientRest
|
||||
{
|
||||
public:
|
||||
bool loadJson(const std::string &json);
|
||||
Maybe<std::string> getNamespaceUidByName(const std::string &name);
|
||||
Maybe<std::string> getNamespaceUidByName(const std::string &name) const;
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string> ns_name_to_uid;
|
||||
|
@ -21,8 +21,8 @@ class OrchestrationPolicy
|
||||
{
|
||||
public:
|
||||
const std::string & getFogAddress() const;
|
||||
const unsigned long & getSleepInterval() const;
|
||||
const unsigned long & getErrorSleepInterval() const;
|
||||
unsigned int getSleepInterval() const;
|
||||
unsigned int getErrorSleepInterval() const;
|
||||
|
||||
void serialize(cereal::JSONInputArchive & archive);
|
||||
|
||||
@ -31,8 +31,8 @@ public:
|
||||
|
||||
private:
|
||||
std::string fog_address;
|
||||
unsigned long sleep_interval;
|
||||
unsigned long error_sleep_interval;
|
||||
unsigned int sleep_interval;
|
||||
unsigned int error_sleep_interval;
|
||||
};
|
||||
|
||||
#endif // __ORCHESTRATION_POLICY_H__
|
||||
|
@ -43,8 +43,8 @@ TEST_F(PolicyTest, serialization)
|
||||
ASSERT_TRUE(false) << "Cereal threw an exception: " << e.what();
|
||||
}
|
||||
|
||||
EXPECT_EQ(15u, orchestration_policy.getErrorSleepInterval());
|
||||
EXPECT_EQ(20u, orchestration_policy.getSleepInterval());
|
||||
EXPECT_EQ(15, orchestration_policy.getErrorSleepInterval());
|
||||
EXPECT_EQ(20, orchestration_policy.getSleepInterval());
|
||||
EXPECT_EQ("http://10.0.0.18:81/control/", orchestration_policy.getFogAddress());
|
||||
}
|
||||
|
||||
@ -63,8 +63,8 @@ TEST_F(PolicyTest, noAgentType)
|
||||
ASSERT_TRUE(false) << "Cereal threw an exception: " << e.what();
|
||||
}
|
||||
|
||||
EXPECT_EQ(15u, orchestration_policy.getErrorSleepInterval());
|
||||
EXPECT_EQ(20u, orchestration_policy.getSleepInterval());
|
||||
EXPECT_EQ(15, orchestration_policy.getErrorSleepInterval());
|
||||
EXPECT_EQ(20, orchestration_policy.getSleepInterval());
|
||||
EXPECT_EQ("http://10.0.0.18:81/control/", orchestration_policy.getFogAddress());
|
||||
}
|
||||
|
||||
@ -83,8 +83,8 @@ TEST_F(PolicyTest, zeroSleepIntervels)
|
||||
ASSERT_TRUE(false) << "Cereal threw an exception: " << e.what();
|
||||
}
|
||||
|
||||
EXPECT_EQ(0u, orchestration_policy.getErrorSleepInterval());
|
||||
EXPECT_EQ(0u, orchestration_policy.getSleepInterval());
|
||||
EXPECT_EQ(0, orchestration_policy.getErrorSleepInterval());
|
||||
EXPECT_EQ(0, orchestration_policy.getSleepInterval());
|
||||
EXPECT_EQ("http://10.0.0.18:81/control/", orchestration_policy.getFogAddress());
|
||||
}
|
||||
|
||||
@ -152,7 +152,7 @@ TEST_F(PolicyTest, newOptionalFields)
|
||||
ASSERT_TRUE(false) << "Cereal threw an exception: " << e.what();
|
||||
}
|
||||
|
||||
EXPECT_EQ(10u, orchestration_policy.getErrorSleepInterval());
|
||||
EXPECT_EQ(30u, orchestration_policy.getSleepInterval());
|
||||
EXPECT_EQ(10, orchestration_policy.getErrorSleepInterval());
|
||||
EXPECT_EQ(30, orchestration_policy.getSleepInterval());
|
||||
EXPECT_EQ("https://fog-api-gw-agents.cloud.ngen.checkpoint.com", orchestration_policy.getFogAddress());
|
||||
}
|
||||
|
@ -59,6 +59,15 @@ TEST_F(URLParserTest, parseAWSWithoutSlash)
|
||||
EXPECT_EQ("", link.getQuery());
|
||||
}
|
||||
|
||||
TEST_F(URLParserTest, setHost)
|
||||
{
|
||||
URLParser link("http://172.23.92.180:180/something");
|
||||
|
||||
EXPECT_EQ(link.getHost(), "172.23.92.180");
|
||||
link.setHost("my.domain");
|
||||
EXPECT_EQ(link.getHost(), "my.domain");
|
||||
}
|
||||
|
||||
TEST_F(URLParserTest, protocolIsMissing)
|
||||
{
|
||||
// HTTPS is set by default when protocol is not present in URL.
|
||||
|
@ -22,13 +22,13 @@ OrchestrationPolicy::getFogAddress() const
|
||||
return fog_address;
|
||||
}
|
||||
|
||||
const unsigned long &
|
||||
unsigned int
|
||||
OrchestrationPolicy::getSleepInterval() const
|
||||
{
|
||||
return sleep_interval;
|
||||
}
|
||||
|
||||
const unsigned long &
|
||||
unsigned int
|
||||
OrchestrationPolicy::getErrorSleepInterval() const
|
||||
{
|
||||
return error_sleep_interval;
|
||||
@ -37,10 +37,13 @@ OrchestrationPolicy::getErrorSleepInterval() const
|
||||
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));
|
||||
try {
|
||||
archive(make_nvp("fog-address", fog_address));
|
||||
archive(make_nvp("pulling-interval", sleep_interval));
|
||||
archive(make_nvp("error-pulling-interval", error_sleep_interval));
|
||||
} catch (const cereal::Exception&) {
|
||||
archive(make_nvp("orchestration", *this));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -399,7 +399,6 @@ public:
|
||||
if (!write_result) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to write Orchestration status. File: " << orchestration_status_path;
|
||||
}
|
||||
dbgTrace(D_ORCHESTRATOR) << "Orchestration status file has been updated. File: " << orchestration_status_path;
|
||||
}
|
||||
|
||||
void
|
||||
@ -459,7 +458,6 @@ public:
|
||||
seconds(5),
|
||||
[this] ()
|
||||
{
|
||||
dbgTrace(D_ORCHESTRATOR) << "Write Orchestration status file <co-routine>";
|
||||
writeStatusToFile();
|
||||
},
|
||||
"Write Orchestration status file"
|
||||
|
@ -129,6 +129,18 @@ URLParser::parseProtocol(const string &url) const
|
||||
return URLProtocol::HTTPS;
|
||||
}
|
||||
|
||||
string
|
||||
URLParser::getHost() const
|
||||
{
|
||||
return host.empty() ? base_url : host;
|
||||
}
|
||||
|
||||
void
|
||||
URLParser::setHost(const string &new_host)
|
||||
{
|
||||
host = new_host;
|
||||
}
|
||||
|
||||
void
|
||||
URLParser::setQuery(const string &new_query)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -108,7 +108,7 @@ NamespaceData::loadJson(const string &json)
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
NamespaceData::getNamespaceUidByName(const string &name)
|
||||
NamespaceData::getNamespaceUidByName(const string &name) const
|
||||
{
|
||||
if (ns_name_to_uid.find(name) == ns_name_to_uid.end()) {
|
||||
return genError("Namespace doesn't exist. Name: " + name);
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
bool removeFile(const string &path) const override;
|
||||
bool copyFile(const string &src_path, const string &dst_path) const override;
|
||||
bool doesFileExist(const string &file_path) const override;
|
||||
void getClusterId() const override;
|
||||
void setClusterId() const override;
|
||||
void fillKeyInJson(const string &filename, const string &_key, const string &_val) const override;
|
||||
bool createDirectory(const string &directory_path) const override;
|
||||
bool doesDirectoryExist(const string &dir_path) const override;
|
||||
@ -143,83 +143,55 @@ isPlaygroundEnv()
|
||||
}
|
||||
|
||||
Maybe<NamespaceData, string>
|
||||
getNamespaceDataFromCluster(const string &path)
|
||||
getNamespaceDataFromCluster()
|
||||
{
|
||||
NamespaceData name_space;
|
||||
string token = Singleton::Consume<I_EnvDetails>::by<OrchestrationTools>()->getToken();
|
||||
auto messaging = Singleton::Consume<I_Messaging>::by<OrchestrationTools>();
|
||||
string auth_header = "Authorization: Bearer " + token;
|
||||
string connection_header = "Connection: close";
|
||||
string host = "https://kubernetes.default.svc:443/api/v1/namespaces/";
|
||||
string culr_cmd = "curl -s -k -H \"" + auth_header + "\" -H \"" + connection_header + "\" " + host +
|
||||
" | /etc/cp/bin/cpnano_json";
|
||||
|
||||
MessageMetadata get_ns_md("kubernetes.default.svc", 443);
|
||||
get_ns_md.insertHeader("Authorization", "Bearer " + token);
|
||||
get_ns_md.insertHeader("Connection", "close");
|
||||
get_ns_md.setConnectioFlag(MessageConnectionConfig::IGNORE_SSL_VALIDATION);
|
||||
auto res = messaging->sendSyncMessage(
|
||||
HTTPMethod::GET,
|
||||
path,
|
||||
name_space,
|
||||
MessageCategory::GENERIC,
|
||||
get_ns_md
|
||||
);
|
||||
auto output_res = Singleton::Consume<I_ShellCmd>::by<OrchestrationTools>()->getExecOutput(culr_cmd);
|
||||
if (!output_res.ok()) {
|
||||
return genError("Failed to get namespace data from the cluster: " + output_res.getErr());
|
||||
}
|
||||
|
||||
if (res.ok()) return name_space;
|
||||
|
||||
return genError(string("Was not able to get object form k8s cluser in path: " + path));
|
||||
dbgTrace(D_ORCHESTRATOR) << "Got the repsonse from the cluster: " << output_res.unpack();
|
||||
NamespaceData name_space;
|
||||
if (name_space.loadJson(output_res.unpack())) return name_space;
|
||||
return genError("Was not able to parse the object form k8s cluser");
|
||||
}
|
||||
|
||||
bool
|
||||
doesClusterIdExists()
|
||||
void
|
||||
OrchestrationTools::Impl::setClusterId() const
|
||||
{
|
||||
auto env_type = Singleton::Consume<I_EnvDetails>::by<OrchestrationTools>()->getEnvType();
|
||||
if (env_type != EnvType::K8S) return;
|
||||
|
||||
dbgTrace(D_ORCHESTRATOR) << "Setting cluster UID";
|
||||
|
||||
Maybe<NamespaceData> namespaces_data = getNamespaceDataFromCluster();
|
||||
if (!namespaces_data.ok()) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to retrieve namespace data. Error: " << namespaces_data.getErr();
|
||||
return;
|
||||
}
|
||||
|
||||
auto ns_uid = (*namespaces_data).getNamespaceUidByName("kube-system");
|
||||
if (!ns_uid.ok()) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to retrieve namespace UID. Error: " << ns_uid.getErr();
|
||||
return;
|
||||
}
|
||||
|
||||
string playground_uid = isPlaygroundEnv() ? "playground-" : "";
|
||||
|
||||
dbgTrace(D_ORCHESTRATOR) << "Getting cluster UID";
|
||||
|
||||
auto maybe_namespaces_data = getNamespaceDataFromCluster("/api/v1/namespaces/");
|
||||
|
||||
if (!maybe_namespaces_data.ok()) {
|
||||
dbgWarning(D_ORCHESTRATOR)
|
||||
<< "Failed to retrieve K8S namespace data. Error: "
|
||||
<< maybe_namespaces_data.getErr();
|
||||
return false;
|
||||
}
|
||||
|
||||
NamespaceData namespaces_data = maybe_namespaces_data.unpack();
|
||||
|
||||
Maybe<string> maybe_ns_uid = namespaces_data.getNamespaceUidByName("kube-system");
|
||||
if (!maybe_ns_uid.ok()) {
|
||||
dbgWarning(D_ORCHESTRATOR) << maybe_ns_uid.getErr();
|
||||
return false;
|
||||
}
|
||||
string uid = playground_uid + maybe_ns_uid.unpack();
|
||||
string uid = playground_uid + ns_uid.unpack();
|
||||
dbgTrace(D_ORCHESTRATOR) << "Found k8s cluster UID: " << uid;
|
||||
I_Environment *env = Singleton::Consume<I_Environment>::by<OrchestrationTools>();
|
||||
env->getConfigurationContext().registerValue<string>(
|
||||
Singleton::Consume<I_Environment>::by<OrchestrationTools>()->getConfigurationContext().registerValue<string>(
|
||||
"k8sClusterId",
|
||||
uid,
|
||||
EnvKeyAttr::LogSection::SOURCE
|
||||
);
|
||||
I_AgentDetails *i_agent_details = Singleton::Consume<I_AgentDetails>::by<OrchestrationTools>();
|
||||
i_agent_details->setClusterId(uid);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
OrchestrationTools::Impl::getClusterId() const
|
||||
{
|
||||
auto env_type = Singleton::Consume<I_EnvDetails>::by<OrchestrationTools>()->getEnvType();
|
||||
|
||||
if (env_type == EnvType::K8S) {
|
||||
Singleton::Consume<I_MainLoop>::by<OrchestrationTools>()->addOneTimeRoutine(
|
||||
I_MainLoop::RoutineType::Offline,
|
||||
[this] ()
|
||||
{
|
||||
while(!doesClusterIdExists()) {
|
||||
Singleton::Consume<I_MainLoop>::by<OrchestrationTools>()->yield(chrono::seconds(1));
|
||||
}
|
||||
return;
|
||||
},
|
||||
"Get k8s cluster ID"
|
||||
);
|
||||
}
|
||||
Singleton::Consume<I_AgentDetails>::by<OrchestrationTools>()->setClusterId(uid);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -77,30 +77,23 @@ TEST_F(OrchestrationToolsTest, doNothing)
|
||||
{
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationToolsTest, getClusterId)
|
||||
TEST_F(OrchestrationToolsTest, setClusterId)
|
||||
{
|
||||
EXPECT_CALL(mock_env_details, getToken()).WillOnce(Return("123"));
|
||||
EXPECT_CALL(mock_env_details, getEnvType()).WillOnce(Return(EnvType::K8S));
|
||||
I_MainLoop::Routine routine;
|
||||
EXPECT_CALL(
|
||||
mock_mainloop,
|
||||
addOneTimeRoutine(I_MainLoop::RoutineType::Offline, _, "Get k8s cluster ID", _)
|
||||
).WillOnce(DoAll(SaveArg<1>(&routine), Return(1)));
|
||||
|
||||
string namespaces = getResource("k8s_namespaces.json");
|
||||
EXPECT_CALL(
|
||||
mock_messaging,
|
||||
sendSyncMessage(
|
||||
HTTPMethod::GET,
|
||||
"/api/v1/namespaces/",
|
||||
_,
|
||||
_,
|
||||
_
|
||||
mock_shell_cmd,
|
||||
getExecOutput(
|
||||
"curl -s -k -H \"Authorization: Bearer 123\" -H \"Connection: close\" "
|
||||
"https://kubernetes.default.svc:443/api/v1/namespaces/ | /etc/cp/bin/cpnano_json",
|
||||
200,
|
||||
false
|
||||
)
|
||||
).WillOnce(Return(HTTPResponse(HTTPStatusCode::HTTP_OK, namespaces)));
|
||||
).WillOnce(Return(namespaces));
|
||||
|
||||
i_orchestration_tools->getClusterId();
|
||||
routine();
|
||||
i_orchestration_tools->setClusterId();
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationToolsTest, writeReadTextToFile)
|
||||
|
@ -24,6 +24,21 @@
|
||||
using namespace testing;
|
||||
using namespace std;
|
||||
|
||||
string host_address = "1.2.3.5";
|
||||
string host_url = "https://" + host_address + "/";
|
||||
Maybe<string> response(
|
||||
string(
|
||||
"{\n"
|
||||
" \"fog-address\": \"" + host_url + "\",\n"
|
||||
" \"agent-type\": \"test\",\n"
|
||||
" \"pulling-interval\": 25,\n"
|
||||
" \"error-pulling-interval\": 15\n"
|
||||
"}"
|
||||
)
|
||||
);
|
||||
string orchestration_policy_file_path = "/etc/cp/conf/orchestration/orchestration.policy";
|
||||
string orchestration_policy_file_path_bk = orchestration_policy_file_path + ".bk";
|
||||
|
||||
class OrchestrationMultitenancyTest : public Test
|
||||
{
|
||||
public:
|
||||
@ -54,6 +69,11 @@ public:
|
||||
void
|
||||
init()
|
||||
{
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path)).WillOnce(Return(response));
|
||||
EXPECT_CALL(mock_status, setFogAddress(host_url)).WillRepeatedly(Return());
|
||||
EXPECT_CALL(mock_orchestration_tools, setClusterId());
|
||||
|
||||
EXPECT_CALL(mock_service_controller, isServiceInstalled("Access Control")).WillRepeatedly(Return(false));
|
||||
|
||||
// This Holding the Main Routine of the Orchestration.
|
||||
@ -62,8 +82,6 @@ public:
|
||||
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Orchestration runner", true)
|
||||
).WillOnce(DoAll(SaveArg<1>(&routine), Return(1)));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, getClusterId());
|
||||
|
||||
EXPECT_CALL(mock_shell_cmd, getExecOutput("openssl version -d | cut -d\" \" -f2 | cut -d\"\\\"\" -f2", _, _))
|
||||
.WillOnce(Return(string("OpenSSL certificates Directory")));
|
||||
|
||||
@ -209,7 +227,6 @@ TEST_F(OrchestrationMultitenancyTest, init)
|
||||
|
||||
TEST_F(OrchestrationMultitenancyTest, handle_virtual_resource)
|
||||
{
|
||||
string orchestration_policy_file_path = "/etc/cp/conf/orchestration/orchestration.policy";
|
||||
string manifest_file_path = "/etc/cp/conf/manifest.json";
|
||||
string setting_file_path = "/etc/cp/conf/settings.json";
|
||||
string policy_file_path = "/etc/cp/conf/policy.json";
|
||||
@ -237,22 +254,6 @@ TEST_F(OrchestrationMultitenancyTest, handle_virtual_resource)
|
||||
init();
|
||||
expectDetailsResolver();
|
||||
|
||||
Maybe<string> response(
|
||||
string(
|
||||
"{\n"
|
||||
" \"fog-address\": \"" + host_url + "\",\n"
|
||||
" \"agent-type\": \"test\",\n"
|
||||
" \"pulling-interval\": 25,\n"
|
||||
" \"error-pulling-interval\": 15\n"
|
||||
"}"
|
||||
)
|
||||
);
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path)).WillOnce(Return(response));
|
||||
EXPECT_CALL(mock_message, setFogConnection(host_address, 443, true, MessageCategory::GENERIC))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion(""));
|
||||
EXPECT_CALL(mock_update_communication, authenticateAgent()).WillOnce(Return(Maybe<void>()));
|
||||
EXPECT_CALL(mock_manifest_controller, loadAfterSelfUpdate()).WillOnce(Return(false));
|
||||
EXPECT_CALL(mock_orchestration_tools, calculateChecksum(Package::ChecksumTypes::SHA256, manifest_file_path))
|
||||
@ -268,7 +269,11 @@ TEST_F(OrchestrationMultitenancyTest, handle_virtual_resource)
|
||||
.WillOnce(Return(data_checksum));
|
||||
|
||||
EXPECT_CALL(mock_service_controller, getPolicyVersion())
|
||||
.Times(2).WillRepeatedly(ReturnRef(first_policy_version));
|
||||
.Times(3).WillRepeatedly(ReturnRef(first_policy_version));
|
||||
|
||||
map<string, PortNumber> empty_service_to_port_map;
|
||||
EXPECT_CALL(mock_service_controller, getServiceToPortMap()).WillRepeatedly(Return(empty_service_to_port_map));
|
||||
|
||||
|
||||
set<string> active_tenants = { "1236", "1235" };
|
||||
map<string, set<string>> old_tenant_profile_set;
|
||||
|
@ -26,6 +26,21 @@
|
||||
using namespace testing;
|
||||
using namespace std;
|
||||
|
||||
string host_address = "1.2.3.5";
|
||||
string host_url = "https://" + host_address + "/";
|
||||
Maybe<string> response(
|
||||
string(
|
||||
"{\n"
|
||||
" \"fog-address\": \"" + host_url + "\",\n"
|
||||
" \"agent-type\": \"test\",\n"
|
||||
" \"pulling-interval\": 25,\n"
|
||||
" \"error-pulling-interval\": 15\n"
|
||||
"}"
|
||||
)
|
||||
);
|
||||
string orchestration_policy_file_path = "/etc/cp/conf/orchestration/orchestration.policy";
|
||||
string orchestration_policy_file_path_bk = orchestration_policy_file_path + ".bk";
|
||||
|
||||
class OrchestrationTest : public testing::TestWithParam<bool>
|
||||
{
|
||||
public:
|
||||
@ -48,14 +63,15 @@ public:
|
||||
void
|
||||
init()
|
||||
{
|
||||
// This Holding the Main Routine of the Orchestration.
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path)).WillOnce(Return(response));
|
||||
EXPECT_CALL(mock_status, setFogAddress(host_url)).WillRepeatedly(Return());
|
||||
EXPECT_CALL(mock_orchestration_tools, setClusterId());
|
||||
EXPECT_CALL(
|
||||
mock_ml,
|
||||
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Orchestration runner", true)
|
||||
).WillOnce(DoAll(SaveArg<1>(&routine), Return(1)));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, getClusterId());
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_shell_cmd,
|
||||
getExecOutput("openssl version -d | cut -d\" \" -f2 | cut -d\"\\\"\" -f2", _, _)
|
||||
@ -270,8 +286,6 @@ public:
|
||||
NiceMock<MockTimeGet> mock_time_get;
|
||||
::Environment env;
|
||||
string first_policy_version = "";
|
||||
string host_address = "1.2.3.5";
|
||||
string host_url = "https://" + host_address + "/";
|
||||
ConfigComponent config_comp;
|
||||
StrictMock<MockEncryptor> mock_encryptor;
|
||||
NiceMock<MockLogging> mock_log;
|
||||
@ -490,27 +504,12 @@ TEST_F(OrchestrationTest, check_sending_registration_data)
|
||||
env.init();
|
||||
init();
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(_)).WillOnce(Return(false));
|
||||
Maybe<string> response(
|
||||
string(
|
||||
"{\n"
|
||||
" \"fog-address\": \"" + host_url + "\",\n"
|
||||
" \"agent-type\": \"test\",\n"
|
||||
" \"pulling-interval\": 25,\n"
|
||||
" \"error-pulling-interval\": 15\n"
|
||||
"}"
|
||||
)
|
||||
);
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(_)).WillOnce(Return(response));
|
||||
EXPECT_CALL(mock_service_controller, updateServiceConfiguration(_, _, _, _, _, _))
|
||||
.WillOnce(Return(Maybe<void>()));
|
||||
EXPECT_CALL(mock_message, setFogConnection(_, _, _, _)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, calculateChecksum(_, _)).WillRepeatedly(Return(string()));
|
||||
EXPECT_CALL(mock_service_controller, getPolicyVersion()).WillRepeatedly(ReturnRef(first_policy_version));
|
||||
EXPECT_CALL(mock_shell_cmd, getExecOutput(_, _, _)).WillRepeatedly(Return(string()));
|
||||
EXPECT_CALL(mock_update_communication, authenticateAgent()).WillOnce(Return(Maybe<void>()));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion(_));
|
||||
EXPECT_CALL(mock_status, setFogAddress(_));
|
||||
EXPECT_CALL(mock_manifest_controller, loadAfterSelfUpdate()).WillOnce(Return(false));
|
||||
expectDetailsResolver();
|
||||
EXPECT_CALL(mock_update_communication, getUpdate(_));
|
||||
@ -554,7 +553,6 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdatRollback)
|
||||
rest,
|
||||
mockRestCall(RestAction::ADD, "proxy", _)
|
||||
).WillOnce(WithArg<2>(Invoke(this, &OrchestrationTest::restHandler)));
|
||||
EXPECT_CALL(mock_status, setFogAddress(host_url)).Times(2);
|
||||
|
||||
string config_json =
|
||||
"{\n"
|
||||
@ -592,17 +590,6 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdatRollback)
|
||||
string second_val = "12";
|
||||
string third_val = "13";
|
||||
|
||||
Maybe<string> policy_response(
|
||||
string(
|
||||
"{\n"
|
||||
" \"fog-address\": \"" + host_url + "\",\n"
|
||||
" \"agent-type\": \"test\",\n"
|
||||
" \"pulling-interval\": 25,\n"
|
||||
" \"error-pulling-interval\": 15\n"
|
||||
"}"
|
||||
)
|
||||
);
|
||||
|
||||
Maybe<string> new_policy_response(
|
||||
string(
|
||||
"{\n"
|
||||
@ -618,20 +605,21 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdatRollback)
|
||||
EXPECT_CALL(mock_service_controller, mockMoveChangedPolicies()).WillOnce(Return(expected_changed_policies));
|
||||
|
||||
EXPECT_CALL(mock_status, setFogAddress(new_host_url));
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path))
|
||||
.WillOnce(Return(true))
|
||||
.WillOnce(Return(true));
|
||||
// Rollback related test: The readFile function is called 3 times:
|
||||
// 1. Read the current policy file
|
||||
// 2. Read the new policy file - The one that should fail
|
||||
// 3. Read the current policy file again - The one that should be restored
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path))
|
||||
.WillOnce(Return(policy_response))
|
||||
.WillOnce(Return(new_policy_response))
|
||||
.WillOnce(Return(policy_response));
|
||||
.WillOnce(Return(response));
|
||||
EXPECT_CALL(mock_orchestration_tools, copyFile(new_policy_path, policy_file_path + ".last"))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_message, setFogConnection(host_address, 443, true, MessageCategory::GENERIC))
|
||||
.Times(2).WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion("")).Times(2);
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion(""));
|
||||
EXPECT_CALL(mock_update_communication, authenticateAgent()).WillOnce(Return(Maybe<void>()));
|
||||
expectDetailsResolver();
|
||||
EXPECT_CALL(mock_manifest_controller, loadAfterSelfUpdate()).WillOnce(Return(false));
|
||||
@ -649,7 +637,8 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdatRollback)
|
||||
|
||||
// Rollback related test: After failing to update the policy file, the policy version should be restored
|
||||
EXPECT_CALL(mock_service_controller, getPolicyVersion())
|
||||
.Times(5)
|
||||
.Times(6)
|
||||
.WillOnce(ReturnRef(first_policy_version))
|
||||
.WillOnce(ReturnRef(first_policy_version))
|
||||
.WillOnce(ReturnRef(first_policy_version))
|
||||
.WillOnce(ReturnRef(second_val))
|
||||
@ -772,7 +761,6 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdate)
|
||||
rest,
|
||||
mockRestCall(RestAction::ADD, "proxy", _)
|
||||
).WillOnce(WithArg<2>(Invoke(this, &OrchestrationTest::restHandler)));
|
||||
EXPECT_CALL(mock_status, setFogAddress(host_url));
|
||||
|
||||
init();
|
||||
|
||||
@ -796,17 +784,6 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdate)
|
||||
string second_val = "12";
|
||||
string third_val = "13";
|
||||
|
||||
Maybe<string> policy_response(
|
||||
string(
|
||||
"{\n"
|
||||
" \"fog-address\": \"" + host_url + "\",\n"
|
||||
" \"agent-type\": \"test\",\n"
|
||||
" \"pulling-interval\": 25,\n"
|
||||
" \"error-pulling-interval\": 15\n"
|
||||
"}"
|
||||
)
|
||||
);
|
||||
|
||||
Maybe<string> new_policy_response(
|
||||
string(
|
||||
"{\n"
|
||||
@ -824,13 +801,9 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdate)
|
||||
EXPECT_CALL(mock_status, setFogAddress(new_host_url));
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path))
|
||||
.WillOnce(Return(policy_response))
|
||||
.WillOnce(Return(new_policy_response));
|
||||
EXPECT_CALL(mock_orchestration_tools, copyFile(new_policy_path, policy_file_path + ".last"))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_message, setFogConnection(host_address, 443, true, MessageCategory::GENERIC))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion(""));
|
||||
EXPECT_CALL(mock_update_communication, authenticateAgent()).WillOnce(Return(Maybe<void>()));
|
||||
expectDetailsResolver();
|
||||
EXPECT_CALL(mock_manifest_controller, loadAfterSelfUpdate()).WillOnce(Return(false));
|
||||
@ -847,7 +820,8 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdate)
|
||||
.WillOnce(Return(data_checksum));
|
||||
|
||||
EXPECT_CALL(mock_service_controller, getPolicyVersion())
|
||||
.Times(4)
|
||||
.Times(5)
|
||||
.WillOnce(ReturnRef(first_policy_version))
|
||||
.WillOnce(ReturnRef(first_policy_version))
|
||||
.WillOnce(ReturnRef(first_policy_version))
|
||||
.WillOnce(ReturnRef(second_val))
|
||||
@ -939,178 +913,52 @@ TEST_F(OrchestrationTest, orchestrationPolicyUpdate)
|
||||
} catch (const invalid_argument& e) {}
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationTest, startOrchestrationPoliceWithFailures)
|
||||
{
|
||||
waitForRestCall();
|
||||
preload();
|
||||
Maybe<string> msg_err = genError("Failed to send message");
|
||||
EXPECT_CALL(mock_status, setFogAddress(host_url));
|
||||
EXPECT_CALL(
|
||||
rest,
|
||||
mockRestCall(RestAction::ADD, "proxy", _)
|
||||
).WillOnce(WithArg<2>(Invoke(this, &OrchestrationTest::restHandler)));
|
||||
init();
|
||||
string orchestration_policy_file_path = getPolicyConfigPath("orchestration", Config::ConfigFileType::Policy);
|
||||
string orchestration_policy_file_path_bk = orchestration_policy_file_path + ".bk";
|
||||
string manifest_file_path = "/etc/cp/conf/manifest.json";
|
||||
string setting_file_path = "/etc/cp/conf/settings.json";
|
||||
string policy_file_path = "/etc/cp/conf/policy.json";
|
||||
string last_policy_file_path = "/etc/cp/conf/policy.json.last";
|
||||
string data_file_path = "/etc/cp/conf/data.json";
|
||||
|
||||
string host_address = "1.2.3.5";
|
||||
string manifest_checksum = "manifest";
|
||||
string policy_checksum = "policy";
|
||||
string settings_checksum = "settings";
|
||||
string data_checksum = "data";
|
||||
|
||||
Maybe<string> response(
|
||||
string(
|
||||
"{\n"
|
||||
" \"fog-address\": \"" + host_url + "\",\n"
|
||||
" \"agent-type\": \"test\",\n"
|
||||
" \"pulling-interval\": 25,\n"
|
||||
" \"error-pulling-interval\": 15\n"
|
||||
"}"
|
||||
)
|
||||
);
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path))
|
||||
.WillOnce(Return(Maybe<string>(genError("Failed"))))
|
||||
.WillOnce(Return(response));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path_bk)).WillOnce(
|
||||
Return(Maybe<string>(genError("Failed")))
|
||||
);
|
||||
|
||||
vector<string> expected_data_types = {};
|
||||
EXPECT_CALL(
|
||||
mock_service_controller,
|
||||
updateServiceConfiguration(policy_file_path, setting_file_path, expected_data_types, "", "", _)
|
||||
).Times(2).WillRepeatedly(Return(Maybe<void>()));
|
||||
|
||||
EXPECT_CALL(mock_message, setFogConnection(host_address, 443, true, MessageCategory::GENERIC))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion(""));
|
||||
EXPECT_CALL(mock_update_communication, authenticateAgent()).WillOnce(Return(Maybe<void>()));
|
||||
expectDetailsResolver();
|
||||
EXPECT_CALL(mock_manifest_controller, loadAfterSelfUpdate()).WillOnce(Return(false));
|
||||
EXPECT_CALL(mock_orchestration_tools, calculateChecksum(Package::ChecksumTypes::SHA256, manifest_file_path))
|
||||
.WillOnce(Return(manifest_checksum));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, calculateChecksum(Package::ChecksumTypes::SHA256, setting_file_path))
|
||||
.WillOnce(Return(settings_checksum));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, calculateChecksum(Package::ChecksumTypes::SHA256, policy_file_path))
|
||||
.WillOnce(Return(policy_checksum));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, calculateChecksum(Package::ChecksumTypes::SHA256, data_file_path))
|
||||
.WillOnce(Return(data_checksum));
|
||||
|
||||
EXPECT_CALL(mock_service_controller, getPolicyVersion())
|
||||
.Times(2).WillRepeatedly(ReturnRef(first_policy_version));
|
||||
|
||||
EXPECT_CALL(mock_update_communication, getUpdate(_)).WillOnce(
|
||||
Invoke(
|
||||
[&](CheckUpdateRequest &req)
|
||||
{
|
||||
EXPECT_THAT(req.getPolicy(), IsValue(policy_checksum));
|
||||
EXPECT_THAT(req.getSettings(), IsValue(settings_checksum));
|
||||
EXPECT_THAT(req.getManifest(), IsValue(manifest_checksum));
|
||||
EXPECT_THAT(req.getData(), IsValue(data_checksum));
|
||||
req = CheckUpdateRequest("", "", "", "", "", "");
|
||||
return Maybe<void>();
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
EXPECT_CALL(mock_status, setLastUpdateAttempt());
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::LAST_UPDATE, OrchestrationStatusResult::SUCCESS, "")
|
||||
);
|
||||
|
||||
EXPECT_CALL(mock_status, setIsConfigurationUpdated(A<EnumArray<OrchestrationStatusConfigType, bool>>())
|
||||
).WillOnce(
|
||||
Invoke(
|
||||
[](EnumArray<OrchestrationStatusConfigType, bool> arr)
|
||||
{
|
||||
EXPECT_EQ(arr[OrchestrationStatusConfigType::MANIFEST], false);
|
||||
EXPECT_EQ(arr[OrchestrationStatusConfigType::POLICY], false);
|
||||
EXPECT_EQ(arr[OrchestrationStatusConfigType::SETTINGS], false);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
EXPECT_CALL(mock_ml, yield(A<chrono::microseconds>()))
|
||||
.WillOnce(
|
||||
Invoke(
|
||||
[] (chrono::microseconds microseconds)
|
||||
{
|
||||
EXPECT_EQ(1000000, microseconds.count());
|
||||
}
|
||||
)
|
||||
)
|
||||
.WillOnce(
|
||||
Invoke(
|
||||
[] (chrono::microseconds microseconds)
|
||||
{
|
||||
EXPECT_EQ(25000000, microseconds.count());
|
||||
throw invalid_argument("stop while loop");
|
||||
}
|
||||
)
|
||||
);
|
||||
EXPECT_CALL(
|
||||
mock_shell_cmd,
|
||||
getExecOutput(_, _, _)
|
||||
).WillRepeatedly(Return(string("daniel\n1\n")));
|
||||
try {
|
||||
runRoutine();
|
||||
} catch (const invalid_argument& e) {}
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationTest, loadOrchestrationPolicyFromBackup)
|
||||
{
|
||||
EXPECT_CALL(
|
||||
rest,
|
||||
mockRestCall(RestAction::ADD, "proxy", _)
|
||||
).WillOnce(WithArg<2>(Invoke(this, &OrchestrationTest::restHandler)));
|
||||
);
|
||||
waitForRestCall();
|
||||
init();
|
||||
string orchestration_policy_file_path = "/etc/cp/conf/orchestration/orchestration.policy";
|
||||
string orchestration_policy_file_path_bk = orchestration_policy_file_path + ".bk";
|
||||
string manifest_file_path = "/etc/cp/conf/manifest.json";
|
||||
string setting_file_path = "/etc/cp/conf/settings.json";
|
||||
string policy_file_path = "/etc/cp/conf/policy.json";
|
||||
string last_policy_file_path = "/etc/cp/conf/policy.json.last";
|
||||
string data_file_path = "/etc/cp/conf/data.json";
|
||||
|
||||
string host_address = "1.2.3.5";
|
||||
string manifest_checksum = "manifest";
|
||||
string policy_checksum = "policy";
|
||||
string settings_checksum = "settings";
|
||||
string data_checksum = "data";
|
||||
EXPECT_CALL(
|
||||
mock_ml,
|
||||
addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, _, "Orchestration runner", true)
|
||||
);
|
||||
|
||||
Maybe<string> response(
|
||||
string(
|
||||
"{\n"
|
||||
" \"fog-address\": \"https://1.2.3.5/\",\n"
|
||||
" \"agent-type\": \"test\",\n"
|
||||
" \"pulling-interval\": 25,\n"
|
||||
" \"error-pulling-interval\": 15\n"
|
||||
"}"
|
||||
EXPECT_CALL(
|
||||
mock_shell_cmd,
|
||||
getExecOutput("openssl version -d | cut -d\" \" -f2 | cut -d\"\\\"\" -f2", _, _)
|
||||
).WillOnce(Return(string("OpenSSL certificates Directory")));
|
||||
|
||||
EXPECT_CALL(mock_service_controller, isServiceInstalled("Access Control")).WillRepeatedly(
|
||||
InvokeWithoutArgs(
|
||||
[]()
|
||||
{
|
||||
static int count = 0;
|
||||
if (count > 0) return false;
|
||||
count++;
|
||||
return true;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
EXPECT_CALL(mock_status, setFogAddress(host_url));
|
||||
map<string, PortNumber> empty_service_to_port_map;
|
||||
EXPECT_CALL(mock_service_controller, getServiceToPortMap()).WillRepeatedly(Return(empty_service_to_port_map));
|
||||
|
||||
EXPECT_CALL(rest, mockRestCall(RestAction::SHOW, "orchestration-status", _));
|
||||
|
||||
vector<string> expected_data_types = {};
|
||||
EXPECT_CALL(
|
||||
mock_service_controller,
|
||||
updateServiceConfiguration(policy_file_path, setting_file_path, expected_data_types, "", "", _)
|
||||
).WillOnce(Return(Maybe<void>()));
|
||||
rest,
|
||||
mockRestCall(RestAction::SET, "agent-uninstall", _)
|
||||
);
|
||||
|
||||
doEncrypt();
|
||||
EXPECT_CALL(mock_orchestration_tools, loadTenantsFromDir(_)).Times(1);
|
||||
|
||||
EXPECT_CALL(mock_status, setFogAddress(host_url));
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, setClusterId());
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path))
|
||||
.WillOnce(Return(Maybe<string>(genError("Failed"))));
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path_bk)).WillOnce(Return(response));
|
||||
@ -1118,81 +966,8 @@ TEST_F(OrchestrationTest, loadOrchestrationPolicyFromBackup)
|
||||
mock_orchestration_tools,
|
||||
copyFile(orchestration_policy_file_path_bk, orchestration_policy_file_path)
|
||||
).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_message, setFogConnection(host_address, 443, true, MessageCategory::GENERIC))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion(""));
|
||||
EXPECT_CALL(mock_update_communication, authenticateAgent()).WillOnce(Return(Maybe<void>()));
|
||||
expectDetailsResolver();
|
||||
EXPECT_CALL(mock_manifest_controller, loadAfterSelfUpdate()).WillOnce(Return(false));
|
||||
EXPECT_CALL(mock_orchestration_tools, calculateChecksum(Package::ChecksumTypes::SHA256, manifest_file_path))
|
||||
.WillOnce(Return(manifest_checksum));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, calculateChecksum(Package::ChecksumTypes::SHA256, setting_file_path))
|
||||
.WillOnce(Return(settings_checksum));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, calculateChecksum(Package::ChecksumTypes::SHA256, policy_file_path))
|
||||
.WillOnce(Return(policy_checksum));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, calculateChecksum(Package::ChecksumTypes::SHA256, data_file_path))
|
||||
.WillOnce(Return(data_checksum));
|
||||
|
||||
EXPECT_CALL(mock_service_controller, getPolicyVersion())
|
||||
.Times(2).WillRepeatedly(ReturnRef(first_policy_version));
|
||||
EXPECT_CALL(mock_update_communication, getUpdate(_)).WillOnce(
|
||||
Invoke(
|
||||
[&](CheckUpdateRequest &req)
|
||||
{
|
||||
EXPECT_THAT(req.getPolicy(), IsValue(policy_checksum));
|
||||
EXPECT_THAT(req.getSettings(), IsValue(settings_checksum));
|
||||
EXPECT_THAT(req.getManifest(), IsValue(manifest_checksum));
|
||||
EXPECT_THAT(req.getData(), IsValue(data_checksum));
|
||||
req = CheckUpdateRequest("", "", "", "", "", "");
|
||||
return Maybe<void>();
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
EXPECT_CALL(mock_status, setLastUpdateAttempt());
|
||||
EXPECT_CALL(
|
||||
mock_status,
|
||||
setFieldStatus(OrchestrationStatusFieldType::LAST_UPDATE, OrchestrationStatusResult::SUCCESS, "")
|
||||
);
|
||||
EXPECT_CALL(mock_status, setIsConfigurationUpdated(A<EnumArray<OrchestrationStatusConfigType, bool>>())
|
||||
).WillOnce(
|
||||
Invoke(
|
||||
[](EnumArray<OrchestrationStatusConfigType, bool> arr)
|
||||
{
|
||||
EXPECT_EQ(arr[OrchestrationStatusConfigType::MANIFEST], false);
|
||||
EXPECT_EQ(arr[OrchestrationStatusConfigType::POLICY], false);
|
||||
EXPECT_EQ(arr[OrchestrationStatusConfigType::SETTINGS], false);
|
||||
}
|
||||
)
|
||||
);
|
||||
EXPECT_CALL(mock_ml, yield(A<chrono::microseconds>()))
|
||||
.WillOnce(
|
||||
Invoke(
|
||||
[] (chrono::microseconds microseconds)
|
||||
{
|
||||
EXPECT_EQ(1000000, microseconds.count());
|
||||
}
|
||||
)
|
||||
)
|
||||
.WillOnce(
|
||||
Invoke(
|
||||
[] (chrono::microseconds microseconds)
|
||||
{
|
||||
EXPECT_EQ(25000000, microseconds.count());
|
||||
throw invalid_argument("stop while loop");
|
||||
}
|
||||
)
|
||||
);
|
||||
EXPECT_CALL(
|
||||
mock_shell_cmd,
|
||||
getExecOutput(_, _, _)
|
||||
).WillRepeatedly(Return(string("daniel\n1\n")));
|
||||
try {
|
||||
runRoutine();
|
||||
} catch (const invalid_argument& e) {}
|
||||
orchestration_comp.init();
|
||||
}
|
||||
|
||||
TEST_F(OrchestrationTest, newServicePolicyUpdate)
|
||||
@ -1213,7 +988,6 @@ TEST_F(OrchestrationTest, manifestUpdate)
|
||||
).WillOnce(WithArg<2>(Invoke(this, &OrchestrationTest::restHandler)));
|
||||
waitForRestCall();
|
||||
init();
|
||||
string orchestration_policy_file_path = "/etc/cp/conf/orchestration/orchestration.policy";
|
||||
string manifest_file_path = "/etc/cp/conf/manifest.json";
|
||||
string setting_file_path = "/etc/cp/conf/settings.json";
|
||||
string policy_file_path = "/etc/cp/conf/policy.json";
|
||||
@ -1226,30 +1000,12 @@ TEST_F(OrchestrationTest, manifestUpdate)
|
||||
string settings_checksum= "settings";
|
||||
string data_checksum = "data";
|
||||
|
||||
EXPECT_CALL(mock_status, setFogAddress(host_url));
|
||||
|
||||
Maybe<string> response(
|
||||
string(
|
||||
"{\n"
|
||||
" \"fog-address\": \"" + host_url + "\",\n"
|
||||
" \"agent-type\": \"test\",\n"
|
||||
" \"pulling-interval\": 25,\n"
|
||||
" \"error-pulling-interval\": 15\n"
|
||||
"}"
|
||||
)
|
||||
);
|
||||
|
||||
vector<string> expected_data_types = {};
|
||||
EXPECT_CALL(
|
||||
mock_service_controller,
|
||||
updateServiceConfiguration(policy_file_path, setting_file_path, expected_data_types, "", "", _)
|
||||
).WillOnce(Return(Maybe<void>()));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path)).WillOnce(Return(response));
|
||||
EXPECT_CALL(mock_message, setFogConnection(host_address, 443, true, MessageCategory::GENERIC))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion(""));
|
||||
EXPECT_CALL(mock_update_communication, authenticateAgent()).WillOnce(Return(Maybe<void>()));
|
||||
expectDetailsResolver();
|
||||
EXPECT_CALL(mock_manifest_controller, loadAfterSelfUpdate()).WillOnce(Return(false));
|
||||
@ -1266,7 +1022,7 @@ TEST_F(OrchestrationTest, manifestUpdate)
|
||||
.WillOnce(Return(data_checksum));
|
||||
|
||||
EXPECT_CALL(mock_service_controller, getPolicyVersion())
|
||||
.Times(2).WillRepeatedly(ReturnRef(first_policy_version));
|
||||
.Times(3).WillRepeatedly(ReturnRef(first_policy_version));
|
||||
EXPECT_CALL(mock_update_communication, getUpdate(_)).WillOnce(
|
||||
Invoke(
|
||||
[&](CheckUpdateRequest &req)
|
||||
@ -1346,7 +1102,6 @@ TEST_F(OrchestrationTest, getBadPolicyUpdate)
|
||||
).WillOnce(WithArg<2>(Invoke(this, &OrchestrationTest::restHandler)));
|
||||
waitForRestCall();
|
||||
init();
|
||||
string orchestration_policy_file_path = "/etc/cp/conf/orchestration/orchestration.policy";
|
||||
string manifest_file_path = "/etc/cp/conf/manifest.json";
|
||||
string setting_file_path = "/etc/cp/conf/settings.json";
|
||||
string policy_file_path = "/etc/cp/conf/policy.json";
|
||||
@ -1359,18 +1114,6 @@ TEST_F(OrchestrationTest, getBadPolicyUpdate)
|
||||
string settings_checksum = "settings";
|
||||
string data_checksum = "data";
|
||||
|
||||
Maybe<string> response(
|
||||
string(
|
||||
"{\n"
|
||||
" \"fog-address\": \"" + host_url + "\",\n"
|
||||
" \"agent-type\": \"test\",\n"
|
||||
" \"pulling-interval\": 25,\n"
|
||||
" \"error-pulling-interval\": 15\n"
|
||||
"}"
|
||||
)
|
||||
);
|
||||
EXPECT_CALL(mock_status, setFogAddress(host_url));
|
||||
|
||||
vector<string> expected_data_types = {};
|
||||
|
||||
EXPECT_CALL(
|
||||
@ -1380,13 +1123,9 @@ TEST_F(OrchestrationTest, getBadPolicyUpdate)
|
||||
|
||||
set<string> expected_changed_policies = {};
|
||||
EXPECT_CALL(mock_service_controller, mockMoveChangedPolicies()).WillOnce(Return(expected_changed_policies));
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path)).WillOnce(Return(response));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, copyFile(new_policy_path, policy_file_path + ".last"))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_message, setFogConnection(host_address, 443, true, MessageCategory::GENERIC))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion(""));
|
||||
|
||||
EXPECT_CALL(mock_update_communication, authenticateAgent()).WillOnce(Return(Maybe<void>()));
|
||||
expectDetailsResolver();
|
||||
@ -1421,7 +1160,8 @@ TEST_F(OrchestrationTest, getBadPolicyUpdate)
|
||||
string second_val = "12";
|
||||
string third_val = "13";
|
||||
EXPECT_CALL(mock_service_controller, getPolicyVersion())
|
||||
.Times(3)
|
||||
.Times(4)
|
||||
.WillOnce(ReturnRef(first_policy_version))
|
||||
.WillOnce(ReturnRef(first_policy_version))
|
||||
.WillOnce(ReturnRef(first_policy_version))
|
||||
.WillOnce(ReturnRef(second_val)
|
||||
@ -1456,7 +1196,7 @@ TEST_F(OrchestrationTest, getBadPolicyUpdate)
|
||||
)
|
||||
);
|
||||
|
||||
EXPECT_CALL(mock_service_controller, getUpdatePolicyVersion()).Times(1).WillOnce(ReturnRef(third_val));
|
||||
EXPECT_CALL(mock_service_controller, getUpdatePolicyVersion()).WillRepeatedly(ReturnRef(third_val));
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_service_controller,
|
||||
@ -1498,7 +1238,6 @@ TEST_F(OrchestrationTest, failedDownloadSettings)
|
||||
).WillOnce(WithArg<2>(Invoke(this, &OrchestrationTest::restHandler)));
|
||||
waitForRestCall();
|
||||
init();
|
||||
string orchestration_policy_file_path = "/etc/cp/conf/orchestration/orchestration.policy";
|
||||
string manifest_file_path = "/etc/cp/conf/manifest.json";
|
||||
string setting_file_path = "/etc/cp/conf/settings.json";
|
||||
string policy_file_path = "/etc/cp/conf/policy.json";
|
||||
@ -1511,30 +1250,12 @@ TEST_F(OrchestrationTest, failedDownloadSettings)
|
||||
string settings_checksum = "settings-checksum";
|
||||
string data_checksum = "data";
|
||||
|
||||
Maybe<string> response(
|
||||
string(
|
||||
"{\n"
|
||||
" \"fog-address\": \"" + host_url + "\",\n"
|
||||
" \"agent-type\": \"test\",\n"
|
||||
" \"pulling-interval\": 25,\n"
|
||||
" \"error-pulling-interval\": 15\n"
|
||||
"}"
|
||||
)
|
||||
);
|
||||
EXPECT_CALL(mock_status, setFogAddress(host_url));
|
||||
|
||||
vector<string> expected_data_types = {};
|
||||
EXPECT_CALL(
|
||||
mock_service_controller,
|
||||
updateServiceConfiguration(policy_file_path, setting_file_path, expected_data_types, "", "", _)
|
||||
).WillOnce(Return(Maybe<void>()));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path)).WillOnce(Return(response));
|
||||
EXPECT_CALL(mock_message, setFogConnection(host_address, 443, true, MessageCategory::GENERIC))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion(""));
|
||||
|
||||
EXPECT_CALL(mock_update_communication, authenticateAgent()).WillOnce(Return(Maybe<void>()));
|
||||
expectDetailsResolver();
|
||||
EXPECT_CALL(mock_manifest_controller, loadAfterSelfUpdate()).WillOnce(Return(false));
|
||||
@ -1553,7 +1274,7 @@ TEST_F(OrchestrationTest, failedDownloadSettings)
|
||||
Maybe<string> new_policy_checksum(string("111111"));
|
||||
|
||||
EXPECT_CALL(mock_service_controller, getPolicyVersion())
|
||||
.Times(2).WillRepeatedly(ReturnRef(first_policy_version));
|
||||
.Times(3).WillRepeatedly(ReturnRef(first_policy_version));
|
||||
EXPECT_CALL(mock_update_communication, getUpdate(_)).WillOnce(
|
||||
Invoke(
|
||||
[&](CheckUpdateRequest &req)
|
||||
@ -1652,7 +1373,6 @@ TEST_P(OrchestrationTest, orchestrationFirstRun)
|
||||
).WillOnce(WithArg<2>(Invoke(this, &OrchestrationTest::restHandler)));
|
||||
waitForRestCall();
|
||||
init();
|
||||
string orchestration_policy_file_path = "/etc/cp/conf/orchestration/orchestration.policy";
|
||||
string manifest_file_path = "/etc/cp/conf/manifest.json";
|
||||
string setting_file_path = "/etc/cp/conf/settings.json";
|
||||
string policy_file_path = "/etc/cp/conf/policy.json";
|
||||
@ -1669,26 +1389,6 @@ TEST_P(OrchestrationTest, orchestrationFirstRun)
|
||||
string policy = "";
|
||||
string setting = "";
|
||||
|
||||
Maybe<string> response(
|
||||
string(
|
||||
"{\n"
|
||||
" \"fog-address\": \"" + host_url + "\",\n"
|
||||
" \"agent-type\": \"test\",\n"
|
||||
" \"pulling-interval\": 25,\n"
|
||||
" \"error-pulling-interval\": 15\n"
|
||||
"}"
|
||||
)
|
||||
);
|
||||
|
||||
EXPECT_CALL(mock_status, setFogAddress(host_url));
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(false));
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path))
|
||||
.WillOnce(Return(response));
|
||||
EXPECT_CALL(mock_message, setFogConnection(host_address, 443, true, MessageCategory::GENERIC)).
|
||||
Times(1).
|
||||
WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion(""));
|
||||
|
||||
EXPECT_CALL(mock_update_communication, authenticateAgent()).WillOnce(Return(Maybe<void>()));
|
||||
expectDetailsResolver();
|
||||
EXPECT_CALL(mock_manifest_controller, loadAfterSelfUpdate()).WillOnce(Return(true));
|
||||
@ -1721,7 +1421,7 @@ TEST_P(OrchestrationTest, orchestrationFirstRun)
|
||||
}
|
||||
)
|
||||
);
|
||||
EXPECT_CALL(mock_service_controller, getPolicyVersion()).WillOnce(ReturnRef(first_policy_version));
|
||||
EXPECT_CALL(mock_service_controller, getPolicyVersion()).WillRepeatedly(ReturnRef(first_policy_version));
|
||||
EXPECT_CALL(mock_update_communication, getUpdate(_)).WillOnce(
|
||||
Invoke(
|
||||
[&](CheckUpdateRequest &req)
|
||||
@ -1854,7 +1554,6 @@ TEST_F(OrchestrationTest, set_proxy)
|
||||
mockRestCall(RestAction::ADD, "proxy", _)
|
||||
).WillOnce(WithArg<2>(Invoke(this, &OrchestrationTest::restHandler)));
|
||||
waitForRestCall();
|
||||
|
||||
init();
|
||||
stringstream is;
|
||||
string proxy_url = "http://some-proxy.com:8080";
|
||||
@ -1873,7 +1572,7 @@ TEST_F(OrchestrationTest, dataUpdate)
|
||||
).WillOnce(WithArg<2>(Invoke(this, &OrchestrationTest::restHandler)));
|
||||
waitForRestCall();
|
||||
init();
|
||||
string orchestration_policy_file_path = "/etc/cp/conf/orchestration/orchestration.policy";
|
||||
|
||||
string manifest_file_path = "/etc/cp/conf/manifest.json";
|
||||
string setting_file_path = "/etc/cp/conf/settings.json";
|
||||
string policy_file_path = "/etc/cp/conf/policy.json";
|
||||
@ -1890,19 +1589,6 @@ TEST_F(OrchestrationTest, dataUpdate)
|
||||
string data_checksum_type = "sha1sum";
|
||||
string data_instance_checksum = "8d4a5709673a05b380ba7d6567e28910019118f5";
|
||||
|
||||
EXPECT_CALL(mock_status, setFogAddress(host_url));
|
||||
|
||||
Maybe<string> policy_response(
|
||||
string(
|
||||
"{\n"
|
||||
" \"fog-address\": \"" + host_url + "\",\n"
|
||||
" \"agent-type\": \"test\",\n"
|
||||
" \"pulling-interval\": 25,\n"
|
||||
" \"error-pulling-interval\": 15\n"
|
||||
"}"
|
||||
)
|
||||
);
|
||||
|
||||
Maybe<string> data_response(
|
||||
string(
|
||||
"{\n"
|
||||
@ -1929,14 +1615,8 @@ TEST_F(OrchestrationTest, dataUpdate)
|
||||
).After(expectation_set).WillOnce(Return(Maybe<void>()));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, doesDirectoryExist("/etc/cp/conf/data")).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(orchestration_policy_file_path)).WillOnce(Return(policy_response));
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(data_file_path + ".download")).WillOnce(Return(data_response));
|
||||
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(orchestration_policy_file_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_message, setFogConnection(host_address, 443, true, MessageCategory::GENERIC))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_update_communication, setAddressExtenesion(""));
|
||||
EXPECT_CALL(mock_update_communication, authenticateAgent()).WillOnce(Return(Maybe<void>()));
|
||||
EXPECT_CALL(mock_manifest_controller, loadAfterSelfUpdate()).WillOnce(Return(false));
|
||||
expectDetailsResolver();
|
||||
@ -1955,8 +1635,7 @@ TEST_F(OrchestrationTest, dataUpdate)
|
||||
EXPECT_CALL(mock_orchestration_tools, calculateChecksum(Package::ChecksumTypes::SHA256, "/path/ips"))
|
||||
.WillOnce(Return(data_instance_checksum));
|
||||
|
||||
EXPECT_CALL(mock_service_controller, getPolicyVersion())
|
||||
.Times(2).WillRepeatedly(ReturnRef(first_policy_version));
|
||||
EXPECT_CALL(mock_service_controller, getPolicyVersion()).WillRepeatedly(ReturnRef(first_policy_version));
|
||||
EXPECT_CALL(mock_update_communication, getUpdate(_)).WillOnce(
|
||||
Invoke(
|
||||
[&](CheckUpdateRequest &req)
|
||||
|
@ -109,6 +109,10 @@ packageHandlerActionsToString(PackageHandlerActions action)
|
||||
installation_mode += " --certs-dir ";
|
||||
installation_mode += trusted_ca_directory.unpack();
|
||||
}
|
||||
|
||||
auto maybe_vs_id = Singleton::Consume<I_Environment>::by<PackageHandler>()->get<string>("VS ID");
|
||||
if (maybe_vs_id.ok()) installation_mode += " --vs_id " + *maybe_vs_id;
|
||||
|
||||
AdditionalFlagsConfiguration additional_flags = getConfigurationWithDefault<AdditionalFlagsConfiguration>(
|
||||
AdditionalFlagsConfiguration(),
|
||||
"orchestration",
|
||||
|
@ -33,7 +33,7 @@
|
||||
using namespace std;
|
||||
using namespace ReportIS;
|
||||
|
||||
USE_DEBUG_FLAG(D_ORCHESTRATOR);
|
||||
USE_DEBUG_FLAG(D_SERVICE_CONTROLLER);
|
||||
|
||||
class SendConfigurations : public ClientRest
|
||||
{
|
||||
@ -56,7 +56,7 @@ public:
|
||||
auto service_controller = Singleton::Consume<I_ServiceController>::by<ServiceReconfStatusMonitor>();
|
||||
if (!finished.get()) {
|
||||
service_controller->updateReconfStatus(id.get(), service_name.get(), ReconfStatus::IN_PROGRESS);
|
||||
dbgTrace(D_ORCHESTRATOR)
|
||||
dbgTrace(D_SERVICE_CONTROLLER)
|
||||
<< "Request for service reconfiguration is still in progress. ID: "
|
||||
<< id.get()
|
||||
<< ", Service Name: "
|
||||
@ -65,7 +65,7 @@ public:
|
||||
}
|
||||
if (error.get()) {
|
||||
service_controller->updateReconfStatus(id.get(), service_name.get(), ReconfStatus::FAILED);
|
||||
dbgError(D_ORCHESTRATOR)
|
||||
dbgError(D_SERVICE_CONTROLLER)
|
||||
<< "Request for service reconfiguration failed to complete. ID: "
|
||||
<< id.get()
|
||||
<< ", Service Name: "
|
||||
@ -75,7 +75,7 @@ public:
|
||||
return;
|
||||
}
|
||||
service_controller->updateReconfStatus(id.get(), service_name.get(), ReconfStatus::SUCCEEDED);
|
||||
dbgInfo(D_ORCHESTRATOR)
|
||||
dbgInfo(D_SERVICE_CONTROLLER)
|
||||
<< "Request for service reconfiguration successfully accomplished. Reconf ID: "
|
||||
<< id.get()
|
||||
<< ", Service Name: "
|
||||
@ -112,7 +112,7 @@ ServiceDetails::isServiceActive() const
|
||||
}
|
||||
}
|
||||
|
||||
dbgDebug(D_ORCHESTRATOR)
|
||||
dbgDebug(D_SERVICE_CONTROLLER)
|
||||
<< "Executing service status check via watchdog api. Service name: "
|
||||
<< service_name
|
||||
<< ", Watchdog command: "
|
||||
@ -133,7 +133,7 @@ ServiceDetails::isServiceActive() const
|
||||
for (int current_attempt = 0; current_attempt < max_retry_attempts; ++current_attempt) {
|
||||
if (service_status.ok() || service_status.getErr().find("Reached timeout") == string::npos) break;
|
||||
|
||||
dbgWarning(D_ORCHESTRATOR)
|
||||
dbgWarning(D_SERVICE_CONTROLLER)
|
||||
<< "Retrying to execute service status check via watchdog API after getting timeout. Service name: "
|
||||
<< service_name
|
||||
<< ", Watchdog command: "
|
||||
@ -146,7 +146,7 @@ ServiceDetails::isServiceActive() const
|
||||
}
|
||||
|
||||
if (!service_status.ok()) {
|
||||
dbgWarning(D_ORCHESTRATOR)
|
||||
dbgWarning(D_SERVICE_CONTROLLER)
|
||||
<< "Changing service status to inactive after failure to its status from watchdog. Service name: "
|
||||
<< service_name
|
||||
<< ", Watchdog output: "
|
||||
@ -154,7 +154,7 @@ ServiceDetails::isServiceActive() const
|
||||
return false;
|
||||
}
|
||||
|
||||
dbgDebug(D_ORCHESTRATOR)
|
||||
dbgDebug(D_SERVICE_CONTROLLER)
|
||||
<< "Successfully retrieved service status from watchdog. Service name: "
|
||||
<< service_name
|
||||
<< ", Watchdog output: "
|
||||
@ -166,7 +166,7 @@ ServiceDetails::isServiceActive() const
|
||||
bool is_registered = status.find("not-registered") == string::npos && status.find("registered") != string::npos;
|
||||
bool is_running = status.find("not-running") == string::npos && status.find("running") != string::npos;
|
||||
|
||||
dbgTrace(D_ORCHESTRATOR)
|
||||
dbgTrace(D_SERVICE_CONTROLLER)
|
||||
<< "Successfully set service status. Service name: "
|
||||
<< service_name
|
||||
<< ", Status: "
|
||||
@ -189,7 +189,7 @@ ReconfStatus
|
||||
ServiceDetails::sendNewConfigurations(int configuration_id, const string &policy_version)
|
||||
{
|
||||
if(!isServiceActive()) {
|
||||
dbgDebug(D_ORCHESTRATOR) << "Service " << service_name << " is inactive";
|
||||
dbgDebug(D_SERVICE_CONTROLLER) << "Service " << service_name << " is inactive";
|
||||
return ReconfStatus::INACTIVE;
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ ServiceDetails::sendNewConfigurations(int configuration_id, const string &policy
|
||||
|
||||
if (!res.ok()) {
|
||||
auto err = res.getErr();
|
||||
dbgDebug(D_ORCHESTRATOR)
|
||||
dbgDebug(D_SERVICE_CONTROLLER)
|
||||
<< "Service: "
|
||||
<< service_name
|
||||
<< " didn't get new configuration. Error: "
|
||||
@ -223,7 +223,7 @@ ServiceDetails::sendNewConfigurations(int configuration_id, const string &policy
|
||||
if (new_config.finished.get()) {
|
||||
if (!new_config.error.get()) {
|
||||
service_details->startReconfStatus(new_config.id.get(), ReconfStatus::SUCCEEDED, service_name, service_id);
|
||||
dbgDebug(D_ORCHESTRATOR) << "Loading service configuration succeeded for service " << service_name;
|
||||
dbgDebug(D_SERVICE_CONTROLLER) << "Loading service configuration succeeded for service " << service_name;
|
||||
return ReconfStatus::SUCCEEDED;
|
||||
} else {
|
||||
string log_name = "Agent could not update policy to version " +
|
||||
@ -241,7 +241,7 @@ ServiceDetails::sendNewConfigurations(int configuration_id, const string &policy
|
||||
<< LogField("policyVersion", service_details->getPolicyVersion());
|
||||
|
||||
service_details->startReconfStatus(new_config.id.get(), ReconfStatus::FAILED, service_name, service_id);
|
||||
dbgDebug(D_ORCHESTRATOR)
|
||||
dbgDebug(D_SERVICE_CONTROLLER)
|
||||
<< "Loading service configuration failed for service "
|
||||
<< service_name
|
||||
<< " with error: "
|
||||
@ -249,7 +249,7 @@ ServiceDetails::sendNewConfigurations(int configuration_id, const string &policy
|
||||
return ReconfStatus::FAILED;
|
||||
}
|
||||
}
|
||||
dbgDebug(D_ORCHESTRATOR) << "Loading service configuration is in progress for service: " << service_name;
|
||||
dbgDebug(D_SERVICE_CONTROLLER) << "Loading service configuration is in progress for service: " << service_name;
|
||||
service_details->startReconfStatus(new_config.id.get(), ReconfStatus::IN_PROGRESS, service_name, service_id);
|
||||
return ReconfStatus::IN_PROGRESS;
|
||||
}
|
||||
@ -257,7 +257,7 @@ ServiceDetails::sendNewConfigurations(int configuration_id, const string &policy
|
||||
void
|
||||
SetNanoServiceConfig::doCall()
|
||||
{
|
||||
dbgFlow(D_ORCHESTRATOR)
|
||||
dbgFlow(D_SERVICE_CONTROLLER)
|
||||
<< "Received registration request from service. Service name: "
|
||||
<< service_name.get()
|
||||
<< ", service listening port: "
|
||||
@ -402,12 +402,12 @@ ServiceController::Impl::getUpdatedReconfStatus()
|
||||
auto maybe_service = getServiceDetails(service_id);
|
||||
|
||||
if (!maybe_service.ok()) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Unable to get service details. Error: " << maybe_service.getErr();
|
||||
dbgWarning(D_SERVICE_CONTROLLER) << "Unable to get service details. Error: " << maybe_service.getErr();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!maybe_service.unpack().isServiceActive()) {
|
||||
dbgInfo(D_ORCHESTRATOR)
|
||||
dbgInfo(D_SERVICE_CONTROLLER)
|
||||
<< "Service is not active, removing from registered services list. Service: "
|
||||
<< services_reconf_names[service_and_reconf_status.first]
|
||||
<< "ID: "
|
||||
@ -490,7 +490,7 @@ ServiceController::Impl::loadRegisteredServicesFromFile()
|
||||
auto maybe_registered_services_str = Singleton::Consume<I_OrchestrationTools>::by<ServiceController::Impl>()->
|
||||
readFile(registered_services_file);
|
||||
if (!maybe_registered_services_str.ok()) {
|
||||
dbgTrace(D_ORCHESTRATOR)
|
||||
dbgTrace(D_SERVICE_CONTROLLER)
|
||||
<< "could not read file. File: "
|
||||
<< registered_services_file
|
||||
<< " Error: " << maybe_registered_services_str.getErr();
|
||||
@ -501,7 +501,7 @@ ServiceController::Impl::loadRegisteredServicesFromFile()
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
ar(cereal::make_nvp("Registered Services", pending_services));
|
||||
|
||||
dbgInfo(D_ORCHESTRATOR)
|
||||
dbgInfo(D_SERVICE_CONTROLLER)
|
||||
<< "Orchestration pending services loaded from file."
|
||||
<< " File: "
|
||||
<< registered_services_file
|
||||
@ -509,7 +509,7 @@ ServiceController::Impl::loadRegisteredServicesFromFile()
|
||||
|
||||
for (const auto &id_service_pair : pending_services) {
|
||||
const auto &service = id_service_pair.second;
|
||||
dbgInfo(D_ORCHESTRATOR)
|
||||
dbgInfo(D_SERVICE_CONTROLLER)
|
||||
<< "Service name: "
|
||||
<< service.getServiceName()
|
||||
<< ", Service ID: "
|
||||
@ -522,7 +522,7 @@ ServiceController::Impl::loadRegisteredServicesFromFile()
|
||||
void
|
||||
ServiceController::Impl::writeRegisteredServicesToFile()
|
||||
{
|
||||
dbgFlow(D_ORCHESTRATOR);
|
||||
dbgFlow(D_SERVICE_CONTROLLER);
|
||||
auto registered_services_file = getConfigurationWithDefault<string>(
|
||||
filesystem_prefix + "/conf/orchestrations_registered_services.json",
|
||||
"orchestration",
|
||||
@ -533,14 +533,14 @@ ServiceController::Impl::writeRegisteredServicesToFile()
|
||||
cereal::JSONOutputArchive ar(ss);
|
||||
ar(cereal::make_nvp("Registered Services", registered_services));
|
||||
|
||||
dbgInfo(D_ORCHESTRATOR)
|
||||
dbgInfo(D_SERVICE_CONTROLLER)
|
||||
<< "Orchestration registered services file has been updated. File: "
|
||||
<< registered_services_file
|
||||
<< ". Registered Services:";
|
||||
|
||||
for (const auto &id_service_pair : registered_services) {
|
||||
const auto &service = id_service_pair.second;
|
||||
dbgInfo(D_ORCHESTRATOR)
|
||||
dbgInfo(D_SERVICE_CONTROLLER)
|
||||
<< "Service name: "
|
||||
<< service.getServiceName()
|
||||
<< ", Service ID: "
|
||||
@ -626,6 +626,7 @@ ServiceController::Impl::registerServiceConfig(
|
||||
|
||||
pending_services.erase(service_config.getServiceID());
|
||||
pending_services.insert({service_config.getServiceID(), service_config});
|
||||
refreshPendingServices();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -639,12 +640,12 @@ ServiceController::Impl::isServiceInstalled(const string &service_name)
|
||||
void
|
||||
ServiceController::Impl::refreshPendingServices()
|
||||
{
|
||||
dbgFlow(D_ORCHESTRATOR);
|
||||
dbgFlow(D_SERVICE_CONTROLLER);
|
||||
if (pending_services.empty()) return;
|
||||
for (const auto &service : pending_services) {
|
||||
registered_services.erase(service.first);
|
||||
registered_services.insert({service.first, service.second});
|
||||
dbgDebug(D_ORCHESTRATOR) << "Successfully registered service. Name: " << service.first;
|
||||
dbgDebug(D_SERVICE_CONTROLLER) << "Successfully registered service. Name: " << service.first;
|
||||
}
|
||||
pending_services.clear();
|
||||
|
||||
@ -659,7 +660,7 @@ ServiceController::Impl::backupConfigurationFile(const string &config_file_path)
|
||||
string backup_file = config_file_path + backup_ext;
|
||||
|
||||
if (!orchestration_tools->doesFileExist(config_file_path)) {
|
||||
dbgTrace(D_ORCHESTRATOR) << "File does not exist. File: " << config_file_path;
|
||||
dbgTrace(D_SERVICE_CONTROLLER) << "File does not exist. File: " << config_file_path;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -670,7 +671,7 @@ ServiceController::Impl::backupConfigurationFile(const string &config_file_path)
|
||||
mainloop->yield(false);
|
||||
}
|
||||
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to back up the file. File: " << config_file_path;
|
||||
dbgWarning(D_SERVICE_CONTROLLER) << "Failed to back up the file. File: " << config_file_path;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -692,12 +693,12 @@ ServiceController::Impl::createDirectoryForChildTenant(
|
||||
if (orchestration_tools->doesDirectoryExist(dir)) return true;
|
||||
|
||||
if (!orchestration_tools->createDirectory(dir)) {
|
||||
dbgError(D_ORCHESTRATOR)
|
||||
dbgError(D_SERVICE_CONTROLLER)
|
||||
<< "Failed to create configuration directory for tenant "
|
||||
<< child_tenant_id;
|
||||
return false;
|
||||
}
|
||||
dbgTrace(D_ORCHESTRATOR) << "Created new configuration directory for tenant " << child_tenant_id;
|
||||
dbgTrace(D_SERVICE_CONTROLLER) << "Created new configuration directory for tenant " << child_tenant_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -716,7 +717,7 @@ getChecksum(const string &file_path)
|
||||
try {
|
||||
checksum = to_string(boost::uuids::random_generator()());
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
dbgDebug(D_ORCHESTRATOR) << "Couldn't generate random checksum";
|
||||
dbgDebug(D_SERVICE_CONTROLLER) << "Couldn't generate random checksum";
|
||||
}
|
||||
return checksum;
|
||||
}
|
||||
@ -734,7 +735,7 @@ ServiceController::Impl::updateServiceConfiguration(
|
||||
if (!child_tenant_id.empty()) {
|
||||
tenant_and_profile_ids = " Child tenant id: " + child_tenant_id + ", Child profile id: " + child_profile_id;
|
||||
}
|
||||
dbgFlow(D_ORCHESTRATOR)
|
||||
dbgFlow(D_SERVICE_CONTROLLER)
|
||||
<< "new_policy_path: "
|
||||
<< new_policy_path
|
||||
<< ", new_settings_path: "
|
||||
@ -758,9 +759,9 @@ ServiceController::Impl::updateServiceConfiguration(
|
||||
}
|
||||
|
||||
for (const string &data : new_data_files) {
|
||||
dbgTrace(D_ORCHESTRATOR) << "data: " << data;
|
||||
dbgTrace(D_SERVICE_CONTROLLER) << "data: " << data;
|
||||
if (service.second.isConfigurationRelevant(data)) {
|
||||
dbgTrace(D_ORCHESTRATOR)
|
||||
dbgTrace(D_SERVICE_CONTROLLER)
|
||||
<< "data has relevant configuration, will update the service: "
|
||||
<< service.first;
|
||||
nano_services_to_update.insert(service.first);
|
||||
@ -770,7 +771,8 @@ ServiceController::Impl::updateServiceConfiguration(
|
||||
}
|
||||
|
||||
if (new_policy_path == "") {
|
||||
dbgDebug(D_ORCHESTRATOR) << "Policy file was not updated. Sending reload command regarding settings and data";
|
||||
dbgDebug(D_SERVICE_CONTROLLER)
|
||||
<< "Policy file was not updated. Sending reload command regarding settings and data";
|
||||
auto signal_services = sendSignalForServices(nano_services_to_update, "");
|
||||
if (!signal_services.ok()) return signal_services.passErr();
|
||||
Singleton::Consume<I_DeclarativePolicy>::from<DeclarativePolicyUtils>()->turnOffApplyPolicyFlag();
|
||||
@ -779,7 +781,7 @@ ServiceController::Impl::updateServiceConfiguration(
|
||||
|
||||
Maybe<string> loaded_policy_json = orchestration_tools->readFile(new_policy_path);
|
||||
if (!loaded_policy_json.ok()) {
|
||||
dbgWarning(D_ORCHESTRATOR)
|
||||
dbgWarning(D_SERVICE_CONTROLLER)
|
||||
<< "Failed to load new file: "
|
||||
<< new_policy_path
|
||||
<< ". Error: "
|
||||
@ -795,7 +797,7 @@ ServiceController::Impl::updateServiceConfiguration(
|
||||
);
|
||||
|
||||
if (!all_security_policies.ok()) {
|
||||
dbgWarning(D_ORCHESTRATOR)
|
||||
dbgWarning(D_SERVICE_CONTROLLER)
|
||||
<< "Failed to parse json file: "
|
||||
<< new_policy_path
|
||||
<< ". Error: "
|
||||
@ -825,13 +827,13 @@ ServiceController::Impl::updateServiceConfiguration(
|
||||
if (child_tenant_id.empty() && single_policy.first == versions_param) {
|
||||
//In a multi-tenant env, only the parent should handle the versions parameter
|
||||
policy_versions = single_policy.second;
|
||||
dbgWarning(D_ORCHESTRATOR) << "Found versions parameter in policy file:" << policy_versions;
|
||||
dbgWarning(D_SERVICE_CONTROLLER) << "Found versions parameter in policy file:" << policy_versions;
|
||||
}
|
||||
|
||||
dbgDebug(D_ORCHESTRATOR) << "Starting to update policy file. Policy type: " << single_policy.first;
|
||||
dbgDebug(D_SERVICE_CONTROLLER) << "Starting to update policy file. Policy type: " << single_policy.first;
|
||||
|
||||
if (!createDirectoryForChildTenant(child_tenant_id, child_profile_id)) {
|
||||
dbgWarning(D_ORCHESTRATOR)
|
||||
dbgWarning(D_SERVICE_CONTROLLER)
|
||||
<< "Failed to create directory for child. Tenant id: " << child_tenant_id
|
||||
<< ", Profile id: " << child_profile_id;
|
||||
return genError("Failed to create directory for child tenant");
|
||||
@ -861,7 +863,7 @@ ServiceController::Impl::updateServiceConfiguration(
|
||||
}
|
||||
changed_policy_files.insert(policy_file_path);
|
||||
|
||||
dbgInfo(D_ORCHESTRATOR) << "Successfully updated policy file. Policy name: " << single_policy.first;
|
||||
dbgInfo(D_SERVICE_CONTROLLER) << "Successfully updated policy file. Policy name: " << single_policy.first;
|
||||
|
||||
auto orc_status = Singleton::Consume<I_OrchestrationStatus>::by<ServiceController>();
|
||||
orc_status->setServiceConfiguration(
|
||||
@ -878,7 +880,9 @@ ServiceController::Impl::updateServiceConfiguration(
|
||||
for (const auto &instance_id: instances) {
|
||||
auto relevant_service = registered_services.find(instance_id);
|
||||
if (relevant_service == registered_services.end()) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Could not find registered service. Service Id: " << instance_id;
|
||||
dbgWarning(D_SERVICE_CONTROLLER)
|
||||
<< "Could not find registered service. Service Id: "
|
||||
<< instance_id;
|
||||
continue;
|
||||
}
|
||||
if (relevant_service->second.isConfigurationRelevant(single_policy.first)) {
|
||||
@ -902,7 +906,7 @@ ServiceController::Impl::updateServiceConfiguration(
|
||||
if (!is_send_signal_for_services.ok()) send_signal_for_services_err = is_send_signal_for_services.getErr();
|
||||
}
|
||||
|
||||
dbgTrace(D_ORCHESTRATOR) << "was policy updated: " << (was_policy_updated ? "true" : "false");
|
||||
dbgTrace(D_SERVICE_CONTROLLER) << "was policy updated: " << (was_policy_updated ? "true" : "false");
|
||||
|
||||
if (was_policy_updated) {
|
||||
string base_path =
|
||||
@ -916,14 +920,14 @@ ServiceController::Impl::updateServiceConfiguration(
|
||||
);
|
||||
|
||||
if (new_policy_path.compare(config_file_path) == 0) {
|
||||
dbgDebug(D_ORCHESTRATOR) << "Enforcing the default policy file";
|
||||
dbgDebug(D_SERVICE_CONTROLLER) << "Enforcing the default policy file";
|
||||
policy_version = version_value;
|
||||
Singleton::Consume<I_DeclarativePolicy>::from<DeclarativePolicyUtils>()->turnOffApplyPolicyFlag();
|
||||
return Maybe<void>();
|
||||
}
|
||||
|
||||
if (!backupConfigurationFile(config_file_path)) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to backup the policy file.";
|
||||
dbgWarning(D_SERVICE_CONTROLLER) << "Failed to backup the policy file.";
|
||||
return genError("Failed to backup the policy file.");
|
||||
}
|
||||
|
||||
@ -931,7 +935,7 @@ ServiceController::Impl::updateServiceConfiguration(
|
||||
|
||||
// Save the new configuration file.
|
||||
if (!orchestration_tools->copyFile(new_policy_path, config_file_path)) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to save the policy file.";
|
||||
dbgWarning(D_SERVICE_CONTROLLER) << "Failed to save the policy file.";
|
||||
return genError("Failed to save the policy file.");
|
||||
}
|
||||
}
|
||||
@ -946,11 +950,11 @@ ServiceController::Impl::sendSignalForServices(
|
||||
const set<string> &nano_services_to_update,
|
||||
const string &policy_version_to_update)
|
||||
{
|
||||
dbgFlow(D_ORCHESTRATOR);
|
||||
dbgFlow(D_SERVICE_CONTROLLER);
|
||||
for (auto &service_id : nano_services_to_update) {
|
||||
auto nano_service = registered_services.find(service_id);
|
||||
if (nano_service == registered_services.end()) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Could not find registered service. Service Id: " << service_id;
|
||||
dbgWarning(D_SERVICE_CONTROLLER) << "Could not find registered service. Service Id: " << service_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -958,13 +962,13 @@ ServiceController::Impl::sendSignalForServices(
|
||||
auto reconf_status = nano_service->second.sendNewConfigurations(configuration_id, policy_version_to_update);
|
||||
|
||||
if (reconf_status == ReconfStatus::INACTIVE) {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Erasing details regarding inactive service " << service_id;
|
||||
dbgWarning(D_SERVICE_CONTROLLER) << "Erasing details regarding inactive service " << service_id;
|
||||
registered_services.erase(service_id);
|
||||
writeRegisteredServicesToFile();
|
||||
}
|
||||
|
||||
if (reconf_status == ReconfStatus::FAILED) {
|
||||
dbgDebug(D_ORCHESTRATOR) << "The reconfiguration failed for serivce: " << service_id;
|
||||
dbgDebug(D_SERVICE_CONTROLLER) << "The reconfiguration failed for serivce: " << service_id;
|
||||
services_reconf_status.clear();
|
||||
services_reconf_names.clear();
|
||||
return genError("The reconfiguration failed for serivce: " + service_id);
|
||||
@ -985,13 +989,14 @@ ServiceController::Impl::sendSignalForServices(
|
||||
while(timer->getMonotonicTime() < current_timeout) {
|
||||
switch (getUpdatedReconfStatus()) {
|
||||
case ReconfStatus::SUCCEEDED: {
|
||||
dbgDebug(D_ORCHESTRATOR) << "The reconfiguration was successfully completed for all the services";
|
||||
dbgDebug(D_SERVICE_CONTROLLER)
|
||||
<< "The reconfiguration was successfully completed for all the services";
|
||||
services_reconf_status.clear();
|
||||
services_reconf_names.clear();
|
||||
return Maybe<void>();
|
||||
}
|
||||
case ReconfStatus::IN_PROGRESS: {
|
||||
dbgTrace(D_ORCHESTRATOR) << "Reconfiguration in progress...";
|
||||
dbgTrace(D_SERVICE_CONTROLLER) << "Reconfiguration in progress...";
|
||||
Singleton::Consume<I_MainLoop>::by<ServiceController>()->yield(chrono::seconds(2));
|
||||
break;
|
||||
}
|
||||
@ -1000,7 +1005,7 @@ ServiceController::Impl::sendSignalForServices(
|
||||
for(auto &status : services_reconf_status) {
|
||||
if (status.second == ReconfStatus::FAILED) {
|
||||
failed_services_vec.push_back(services_reconf_names[status.first]);
|
||||
dbgDebug(D_ORCHESTRATOR)
|
||||
dbgDebug(D_SERVICE_CONTROLLER)
|
||||
<< "The reconfiguration failed for serivce "
|
||||
<< services_reconf_names[status.first];
|
||||
}
|
||||
@ -1013,7 +1018,7 @@ ServiceController::Impl::sendSignalForServices(
|
||||
return genError("The reconfiguration failed for serivces: " + failed_services);
|
||||
}
|
||||
case ReconfStatus::INACTIVE: {
|
||||
dbgError(D_ORCHESTRATOR) << "Reached inactive state in the middle of reconfiguration!";
|
||||
dbgError(D_SERVICE_CONTROLLER) << "Reached inactive state in the middle of reconfiguration!";
|
||||
services_reconf_status.clear();
|
||||
services_reconf_names.clear();
|
||||
return genError("Reached inactive state in the middle of reconfiguration!");
|
||||
@ -1021,7 +1026,7 @@ ServiceController::Impl::sendSignalForServices(
|
||||
}
|
||||
}
|
||||
|
||||
dbgDebug(D_ORCHESTRATOR) << "The reconfiguration has reached a timeout";
|
||||
dbgDebug(D_SERVICE_CONTROLLER) << "The reconfiguration has reached a timeout";
|
||||
services_reconf_status.clear();
|
||||
services_reconf_names.clear();
|
||||
return genError("The reconfiguration has reached a timeout");
|
||||
@ -1033,17 +1038,17 @@ ServiceController::Impl::updateServiceConfigurationFile(
|
||||
const string &configuration_file_path,
|
||||
const string &new_configuration)
|
||||
{
|
||||
dbgFlow(D_ORCHESTRATOR) << "Updating configuration. Config Name: " << configuration_name;
|
||||
dbgFlow(D_SERVICE_CONTROLLER) << "Updating configuration. Config Name: " << configuration_name;
|
||||
|
||||
if (orchestration_tools->doesFileExist(configuration_file_path)) {
|
||||
Maybe<string> old_configuration = orchestration_tools->readFile(configuration_file_path);
|
||||
if (old_configuration.ok()) {
|
||||
bool service_changed = old_configuration.unpack().compare(new_configuration) != 0;
|
||||
if (service_changed == false) {
|
||||
dbgDebug(D_ORCHESTRATOR) << "There is no update for policy file: " << configuration_file_path;
|
||||
dbgDebug(D_SERVICE_CONTROLLER) << "There is no update for policy file: " << configuration_file_path;
|
||||
return Maybe<void>();
|
||||
}
|
||||
dbgDebug(D_ORCHESTRATOR)
|
||||
dbgDebug(D_SERVICE_CONTROLLER)
|
||||
<< "Starting to update " << configuration_file_path << " to " << new_configuration;
|
||||
string old_configuration_backup_path = configuration_file_path + getConfigurationWithDefault<string>(
|
||||
".bk",
|
||||
@ -1051,13 +1056,15 @@ ServiceController::Impl::updateServiceConfigurationFile(
|
||||
"Backup file extension"
|
||||
);
|
||||
if (orchestration_tools->copyFile(configuration_file_path, old_configuration_backup_path)) {
|
||||
dbgDebug(D_ORCHESTRATOR) << "Backup of policy file has been created in: " << configuration_file_path;
|
||||
dbgDebug(D_SERVICE_CONTROLLER)
|
||||
<< "Backup of policy file has been created in: "
|
||||
<< configuration_file_path;
|
||||
} else {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to backup policy file";
|
||||
dbgWarning(D_SERVICE_CONTROLLER) << "Failed to backup policy file";
|
||||
return genError("Failed to backup policy file");
|
||||
}
|
||||
} else {
|
||||
dbgWarning(D_ORCHESTRATOR)
|
||||
dbgWarning(D_SERVICE_CONTROLLER)
|
||||
<< "Failed to read current policy file "
|
||||
<< configuration_file_path
|
||||
<< ". Error: "
|
||||
@ -1073,13 +1080,13 @@ ServiceController::Impl::updateServiceConfigurationFile(
|
||||
}
|
||||
|
||||
if (orchestration_tools->writeFile(new_configuration, configuration_file_path)) {
|
||||
dbgDebug(D_ORCHESTRATOR) << "New policy file has been saved in: " << configuration_file_path;
|
||||
dbgDebug(D_SERVICE_CONTROLLER) << "New policy file has been saved in: " << configuration_file_path;
|
||||
} else {
|
||||
dbgWarning(D_ORCHESTRATOR) << "Failed to save new policy file";
|
||||
dbgWarning(D_SERVICE_CONTROLLER) << "Failed to save new policy file";
|
||||
return genError("Failed to save new policy file");
|
||||
}
|
||||
|
||||
dbgInfo(D_ORCHESTRATOR) << "Successfully updated policy file: " << configuration_file_path;
|
||||
dbgInfo(D_SERVICE_CONTROLLER) << "Successfully updated policy file: " << configuration_file_path;
|
||||
|
||||
return Maybe<void>();
|
||||
}
|
||||
@ -1120,14 +1127,14 @@ ServiceController::Impl::updateReconfStatus(int id, const string &service_name,
|
||||
}
|
||||
|
||||
if (services_reconf_status.find(id) == services_reconf_status.end()) {
|
||||
dbgError(D_ORCHESTRATOR)
|
||||
dbgError(D_SERVICE_CONTROLLER)
|
||||
<< "Unable to find a mapping for reconfiguration ID:"
|
||||
<< id
|
||||
<< ". Service name: "
|
||||
<< service_name;
|
||||
return;
|
||||
}
|
||||
dbgTrace(D_ORCHESTRATOR)
|
||||
dbgTrace(D_SERVICE_CONTROLLER)
|
||||
<< "Updating reconf status for reconfiguration ID "
|
||||
<< id
|
||||
<< ", Service name: "
|
||||
@ -1144,7 +1151,7 @@ ServiceController::Impl::startReconfStatus(
|
||||
const string &service_name,
|
||||
const string &service_id)
|
||||
{
|
||||
dbgTrace(D_ORCHESTRATOR)
|
||||
dbgTrace(D_SERVICE_CONTROLLER)
|
||||
<< "Starting reconf status. Configuration ID: "
|
||||
<< id
|
||||
<< ", service name: "
|
||||
|
@ -21,15 +21,13 @@
|
||||
using namespace testing;
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_SERVICE_CONTROLLER);
|
||||
|
||||
class ServiceControllerTest : public Test
|
||||
{
|
||||
public:
|
||||
ServiceControllerTest()
|
||||
{
|
||||
Debug::setUnitTestFlag(D_ORCHESTRATOR, Debug::DebugLevel::NOISE);
|
||||
Debug::setNewDefaultStdout(&capture_debug);
|
||||
|
||||
CPTestTempfile status_file;
|
||||
registered_services_file_path = status_file.fname;
|
||||
setConfiguration(registered_services_file_path, "orchestration", "Orchestration registered services");
|
||||
|
||||
@ -116,28 +114,6 @@ public:
|
||||
Debug::setNewDefaultStdout(&cout);
|
||||
}
|
||||
|
||||
void
|
||||
registerNewService()
|
||||
{
|
||||
stringstream new_service_registration;
|
||||
new_service_registration
|
||||
<< "{"
|
||||
<< " \"service_name\": \"mock access control\","
|
||||
<< " \"service_listening_port\":" + to_string(l4_firewall_service_port) + ","
|
||||
<< " \"expected_configurations\": [\"l4_firewall\", \"non updated capability\"],"
|
||||
<< " \"service_id\": \"family1_id2\","
|
||||
<< " \"general_settings\": \"path_to_settings\","
|
||||
<< " \"debug_settings\": \"path_to_debug\""
|
||||
<< "}";
|
||||
|
||||
auto registration_res = set_nano_service_config->performRestCall(new_service_registration);
|
||||
ASSERT_TRUE(registration_res.ok());
|
||||
|
||||
i_service_controller = Singleton::Consume<I_ServiceController>::from(service_controller);
|
||||
EXPECT_TRUE(i_service_controller->isServiceInstalled("family1_id2"));
|
||||
EXPECT_FALSE(i_service_controller->isServiceInstalled("I am not installed"));
|
||||
}
|
||||
|
||||
string
|
||||
orchestrationRegisteredServicesFileToString(const string &file_name)
|
||||
{
|
||||
@ -159,6 +135,43 @@ public:
|
||||
return string_stream.str();
|
||||
}
|
||||
|
||||
void
|
||||
registerNewService()
|
||||
{
|
||||
stringstream new_service_registration;
|
||||
new_service_registration
|
||||
<< "{"
|
||||
<< " \"service_name\": \"mock access control\","
|
||||
<< " \"service_listening_port\":" + to_string(l4_firewall_service_port) + ","
|
||||
<< " \"expected_configurations\": [\"l4_firewall\", \"non updated capability\"],"
|
||||
<< " \"service_id\": \"family1_id2\","
|
||||
<< " \"general_settings\": \"path_to_settings\","
|
||||
<< " \"debug_settings\": \"path_to_debug\""
|
||||
<< "}";
|
||||
|
||||
auto registration_res = set_nano_service_config->performRestCall(new_service_registration);
|
||||
ASSERT_TRUE(registration_res.ok());
|
||||
|
||||
i_service_controller = Singleton::Consume<I_ServiceController>::from(service_controller);
|
||||
EXPECT_TRUE(i_service_controller->isServiceInstalled("family1_id2"));
|
||||
EXPECT_FALSE(i_service_controller->isServiceInstalled("I am not installed"));
|
||||
|
||||
string expected_json = "{\n"
|
||||
" \"Registered Services\": {\n"
|
||||
" \"family1_id2\": {\n"
|
||||
" \"Service name\": \"mock access control\",\n"
|
||||
" \"Service ID\": \"family1_id2\",\n"
|
||||
" \"Service port\": " + to_string(l4_firewall_service_port) + ",\n"
|
||||
" \"Relevant configs\": [\n"
|
||||
" \"non updated capability\",\n"
|
||||
" \"l4_firewall\"\n"
|
||||
" ]\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}";
|
||||
EXPECT_EQ(orchestrationRegisteredServicesFileToString(registered_services_file_path), expected_json);
|
||||
}
|
||||
|
||||
void
|
||||
expectNewConfigRequest(const string &req_body, const string &response)
|
||||
{
|
||||
@ -174,6 +187,7 @@ public:
|
||||
).WillOnce(Return(HTTPResponse(HTTPStatusCode::HTTP_OK, response)));
|
||||
}
|
||||
|
||||
CPTestTempfile status_file;
|
||||
const uint16_t l4_firewall_service_port = 8888;
|
||||
const uint16_t waap_service_port = 7777;
|
||||
::Environment env;
|
||||
@ -193,7 +207,7 @@ public:
|
||||
string services_port;
|
||||
StrictMock<MockTimeGet> time;
|
||||
StrictMock<MockRestApi> mock_rest_api;
|
||||
StrictMock<MockMessaging> mock_message;
|
||||
StrictMock<MockMessaging> mock_message;
|
||||
StrictMock<MockMainLoop> mock_ml;
|
||||
StrictMock<MockShellCmd> mock_shell_cmd;
|
||||
StrictMock<MockOrchestrationStatus> mock_orchestration_status;
|
||||
@ -206,11 +220,10 @@ public:
|
||||
unique_ptr<ServerRest> get_services_ports;
|
||||
unique_ptr<ServerRest> set_reconf_status;
|
||||
unique_ptr<ServerRest> set_new_configuration;
|
||||
|
||||
I_MainLoop::Routine v_tenants_cleanup;
|
||||
I_MainLoop::Routine v_tenants_cleanup;
|
||||
ostringstream capture_debug;
|
||||
string version_value = "1.0.2";
|
||||
string old_version = "1.0.1";
|
||||
string version_value = "1.0.2";
|
||||
string old_version = "1.0.1";
|
||||
};
|
||||
|
||||
TEST_F(ServiceControllerTest, doNothing)
|
||||
@ -494,103 +507,6 @@ TEST_F(ServiceControllerTest, TimeOutUpdateConfiguration)
|
||||
EXPECT_EQ(i_service_controller->getUpdatePolicyVersion(), version_value);
|
||||
}
|
||||
|
||||
TEST_F(ServiceControllerTest, writeRegisteredServicesFromFile)
|
||||
{
|
||||
EXPECT_EQ(orchestrationRegisteredServicesFileToString(registered_services_file_path), string(""));
|
||||
|
||||
string new_configuration = "{"
|
||||
" \"version\": \"" + version_value + "\""
|
||||
" \"l4_firewall\":"
|
||||
" {"
|
||||
" \"app\": \"netfilter\","
|
||||
" \"l4_firewall_rules\": ["
|
||||
" {"
|
||||
" \"name\": \"allow_statefull_conns\","
|
||||
" \"flags\": [\"established\"],"
|
||||
" \"action\": \"accept\""
|
||||
" },"
|
||||
" {"
|
||||
" \"name\": \"icmp drop\","
|
||||
" \"flags\": [\"log\"],"
|
||||
" \"services\": [{\"name\":\"icmp\"}],"
|
||||
" \"action\": \"drop\""
|
||||
" }"
|
||||
" ]"
|
||||
" }"
|
||||
"}";
|
||||
|
||||
string l4_firewall = "{"
|
||||
" \"app\": \"netfilter\","
|
||||
" \"l4_firewall_rules\": ["
|
||||
" {"
|
||||
" \"name\": \"allow_statefull_conns\","
|
||||
" \"flags\": [\"established\"],"
|
||||
" \"action\": \"accept\""
|
||||
" },"
|
||||
" {"
|
||||
" \"name\": \"icmp drop\","
|
||||
" \"flags\": [\"log\"],"
|
||||
" \"services\": [{\"name\":\"icmp\"}],"
|
||||
" \"action\": \"drop\""
|
||||
" }"
|
||||
" ]"
|
||||
"}";
|
||||
string expected_json = "{\n"
|
||||
" \"Registered Services\": {\n"
|
||||
" \"family1_id2\": {\n"
|
||||
" \"Service name\": \"mock access control\",\n"
|
||||
" \"Service ID\": \"family1_id2\",\n"
|
||||
" \"Service port\": 8888,\n"
|
||||
" \"Relevant configs\": [\n"
|
||||
" \"non updated capability\",\n"
|
||||
" \"l4_firewall\"\n"
|
||||
" ]\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}";
|
||||
|
||||
Maybe<map<string, string>> json_parser_return =
|
||||
map<string, string>({{"l4_firewall", l4_firewall}, {"version", version_value}});
|
||||
EXPECT_CALL(mock_orchestration_tools, readFile(file_name)).WillOnce(Return(new_configuration));
|
||||
EXPECT_CALL(mock_orchestration_tools, jsonObjectSplitter(new_configuration, _, _))
|
||||
.WillOnce(Return(json_parser_return));
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(l4_firewall_policy_path)).WillOnce(Return(false));
|
||||
EXPECT_CALL(mock_orchestration_tools, writeFile(l4_firewall, l4_firewall_policy_path, false))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_status,
|
||||
setServiceConfiguration("l4_firewall", l4_firewall_policy_path, OrchestrationStatusConfigType::POLICY));
|
||||
|
||||
EXPECT_EQ(i_service_controller->getPolicyVersion(), "");
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, calculateChecksum(Package::ChecksumTypes::MD5, file_name))
|
||||
.WillOnce(Return(version_value));
|
||||
|
||||
EXPECT_CALL(mock_orchestration_tools, copyFile(policy_file_path, policy_file_path + backup_extension))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, copyFile(file_name, policy_file_path)).WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_orchestration_tools, doesFileExist(policy_file_path)).WillOnce(Return(true));
|
||||
|
||||
string general_settings_path = "/my/settings/path";
|
||||
string reply_msg = "{\"id\": 1, \"error\": false, \"finished\": true, \"error_message\": \"\"}";
|
||||
|
||||
expectNewConfigRequest("{\n \"id\": 1,\n \"policy_version\": \"1.0.2,1.0.2\"\n}", reply_msg);
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_shell_cmd,
|
||||
getExecOutput(
|
||||
"/etc/cp/watchdog/cp-nano-watchdog --status --verbose --service mock access control"
|
||||
" --family family1 --id id2",
|
||||
_,
|
||||
_
|
||||
)
|
||||
).WillRepeatedly(Return(string("registered and running")));
|
||||
|
||||
EXPECT_TRUE(i_service_controller->updateServiceConfiguration(file_name, general_settings_path).ok());
|
||||
EXPECT_EQ(i_service_controller->getPolicyVersion(), version_value);
|
||||
EXPECT_EQ(i_service_controller->getUpdatePolicyVersion(), version_value);
|
||||
EXPECT_EQ(orchestrationRegisteredServicesFileToString(registered_services_file_path), expected_json);
|
||||
}
|
||||
|
||||
TEST_F(ServiceControllerTest, readRegisteredServicesFromFile)
|
||||
{
|
||||
int family1_id3_port = 1111;
|
||||
@ -1409,6 +1325,8 @@ TEST_F(ServiceControllerTest, failingWhileCopyingCurrentConfiguration)
|
||||
|
||||
TEST_F(ServiceControllerTest, ErrorUpdateConfigurationRest)
|
||||
{
|
||||
Debug::setUnitTestFlag(D_SERVICE_CONTROLLER, Debug::DebugLevel::NOISE);
|
||||
Debug::setNewDefaultStdout(&capture_debug);
|
||||
string new_configuration = "{"
|
||||
" \"version\": \"" + version_value + "\""
|
||||
" \"l4_firewall\":"
|
||||
|
@ -17,11 +17,11 @@
|
||||
#include <dirent.h>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <boost/regex.hpp>
|
||||
#include <iostream>
|
||||
#include <cctype>
|
||||
|
||||
#include "agent_core_utilities.h"
|
||||
|
||||
#include "cereal/archives/json.hpp"
|
||||
|
||||
#include "debug.h"
|
||||
#include "cereal/external/rapidjson/error/en.h"
|
||||
#include "include/profile_settings.h"
|
||||
@ -158,6 +158,7 @@ private:
|
||||
vector<string> fillMultiTenantConfigFiles(const map<string, set<string>> &tenants);
|
||||
vector<string> fillMultiTenantExpectedConfigFiles(const map<string, set<string>> &tenants);
|
||||
map<string, string> getProfileAgentSetting() const;
|
||||
void resolveVsId() const;
|
||||
|
||||
string
|
||||
getActiveTenant() const
|
||||
@ -243,7 +244,7 @@ private:
|
||||
dbgTrace(D_CONFIG) << "File system path reloaded: " << config_directory_path;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
sendOrchestatorReloadStatusMsg(const LoadNewConfigurationStatus &status)
|
||||
{
|
||||
I_Messaging *messaging = Singleton::Consume<I_Messaging>::by<ConfigComponent>();
|
||||
@ -261,7 +262,7 @@ private:
|
||||
MessageMetadata secondary_port_req_md("127.0.0.1", 7778);
|
||||
secondary_port_req_md.setConnectioFlag(MessageConnectionConfig::ONE_TIME_CONN);
|
||||
secondary_port_req_md.setConnectioFlag(MessageConnectionConfig::UNSECURE_CONN);
|
||||
service_config_status = messaging->sendSyncMessageWithoutResponse(
|
||||
messaging->sendSyncMessageWithoutResponse(
|
||||
HTTPMethod::POST,
|
||||
"/set-reconf-status",
|
||||
status,
|
||||
@ -269,11 +270,6 @@ private:
|
||||
secondary_port_req_md
|
||||
);
|
||||
}
|
||||
if (!service_config_status) {
|
||||
dbgWarning(D_CONFIG) << "Unsuccessful attempt to send configuration reload status";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
unordered_map<TenantProfilePair, map<vector<string>, PerContextValue>> configuration_nodes;
|
||||
@ -339,6 +335,9 @@ void
|
||||
ConfigComponent::Impl::init()
|
||||
{
|
||||
reloadFileSystemPaths();
|
||||
|
||||
resolveVsId();
|
||||
|
||||
tenant_manager = Singleton::Consume<I_TenantManager>::by<ConfigComponent>();
|
||||
|
||||
if (!Singleton::exists<I_MainLoop>()) return;
|
||||
@ -354,8 +353,7 @@ ConfigComponent::Impl::init()
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
static bool
|
||||
checkContext(const shared_ptr<EnvironmentEvaluator<bool>> &ctx)
|
||||
{
|
||||
if (ctx == nullptr) return true;
|
||||
@ -937,19 +935,31 @@ ConfigComponent::Impl::reloadConfigurationContinuesWrapper(const string &version
|
||||
mainloop->stop(routine_id);
|
||||
LoadNewConfigurationStatus finished(id, service_name, !res, true);
|
||||
if (!res) finished.setError("Failed to reload configuration");
|
||||
I_TimeGet *time = Singleton::Consume<I_TimeGet>::by<ConfigComponent>();
|
||||
auto send_status_time_out = time->getMonotonicTime() + chrono::seconds(180);
|
||||
while (time->getMonotonicTime() < send_status_time_out) {
|
||||
if (sendOrchestatorReloadStatusMsg(finished)) break;
|
||||
mainloop->yield(chrono::seconds(1));
|
||||
}
|
||||
if (time->getMonotonicTime() >= send_status_time_out) {
|
||||
dbgWarning(D_CONFIG) << "Failed to send configuration reload status(finish) to the orchestrator";
|
||||
}
|
||||
sendOrchestatorReloadStatusMsg(finished);
|
||||
|
||||
is_continuous_report = false;
|
||||
}
|
||||
|
||||
void
|
||||
ConfigComponent::Impl::resolveVsId() const
|
||||
{
|
||||
const string &path = getConfigurationFlag("filesystem_path");
|
||||
|
||||
size_t vs_pos = path.rfind("/vs");
|
||||
if (vs_pos == string::npos) return;
|
||||
|
||||
string vs_id = path.substr(vs_pos + 3);
|
||||
|
||||
if (!vs_id.empty() && all_of(vs_id.begin(), vs_id.end(), ::isdigit) && vs_id.size() < 6) {
|
||||
dbgDebug(D_CONFIG) << "Identified VSX installation, VS ID: " << vs_id;
|
||||
Singleton::Consume<I_Environment>::by<ConfigComponent>()->registerValue("VS ID", vs_id);
|
||||
return;
|
||||
}
|
||||
|
||||
dbgWarning(D_CONFIG) << "Possible VSX installation but VS ID is invalid, VS ID: " << vs_id;
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigComponent::ConfigComponent() : Component("ConfigComponent"), pimpl(make_unique<Impl>()) {}
|
||||
ConfigComponent::~ConfigComponent() {}
|
||||
|
||||
|
@ -80,4 +80,13 @@ enum class HTTPStatusCode
|
||||
HTTP_SUSPEND = -2
|
||||
};
|
||||
|
||||
enum class BioConnectionStatus
|
||||
{
|
||||
SUCCESS,
|
||||
SHOULD_RETRY,
|
||||
SHOULD_NOT_RETRY,
|
||||
|
||||
COUNT
|
||||
};
|
||||
|
||||
#endif // __MESSAGING_ENUMS_H__
|
||||
|
@ -134,6 +134,7 @@ DEFINE_FLAG(D_COMPONENT, D_ALL)
|
||||
DEFINE_FLAG(D_AGENT_DETAILS, D_ORCHESTRATOR)
|
||||
DEFINE_FLAG(D_LOCAL_POLICY, D_ORCHESTRATOR)
|
||||
DEFINE_FLAG(D_NGINX_POLICY, D_ORCHESTRATOR)
|
||||
DEFINE_FLAG(D_SERVICE_CONTROLLER, D_ORCHESTRATOR)
|
||||
|
||||
DEFINE_FLAG(D_GRADUAL_DEPLOYMENT, D_COMPONENT)
|
||||
DEFINE_FLAG(D_SDWAN, D_COMPONENT)
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <cereal/archives/json.hpp>
|
||||
|
||||
#include "maybe_res.h"
|
||||
#include "enum_array.h"
|
||||
@ -31,26 +32,46 @@ enum class ClassifierType { CLASS, CATEGORY, FAMILY, GROUP, ORDER, KIND };
|
||||
enum class ObjectType { ASSET, ZONE, POLICY_PACKAGE, CONFIGURATION, SESSION, SHORTLIVED };
|
||||
enum class InvalidationType { ADD, DELETE, UPDATE };
|
||||
|
||||
class StrAttributes
|
||||
{
|
||||
public:
|
||||
StrAttributes() = default;
|
||||
StrAttributes & addStringAttr(const std::string &attr, const std::string &val);
|
||||
StrAttributes & addStringSetAttr(const std::string &attr, const std::set<std::string> &val);
|
||||
Maybe<std::string, void> getStringAttr(const std::string &attr) const;
|
||||
Maybe<std::set<std::string>, void> getStringSetAttr(const std::string &attr) const;
|
||||
Maybe<std::string, void> genObject() const;
|
||||
bool isEmpty() const;
|
||||
bool matches(const StrAttributes &other) const;
|
||||
void serialize(cereal::JSONInputArchive &ar);
|
||||
void performOutputingSchema(std::ostream &, int);
|
||||
|
||||
private:
|
||||
bool hasAttr(const std::string &key, const std::string &value) const;
|
||||
|
||||
std::map<std::string, std::string> string_attr;
|
||||
std::map<std::string, std::set<std::string>> set_string_attr;
|
||||
};
|
||||
|
||||
class Invalidation
|
||||
{
|
||||
public:
|
||||
Invalidation(const std::string &class_value);
|
||||
|
||||
Invalidation & setClassifier(ClassifierType type, const std::string &val);
|
||||
Invalidation & setStringAttr(const std::string &attr, const std::string &val, bool is_main = true);
|
||||
Invalidation & setStringSetAttr(const std::string &attr, const std::set<std::string> &val, bool is_main = true);
|
||||
Invalidation & addMainAttr(const StrAttributes &attr);
|
||||
Invalidation & addAttr(const StrAttributes &attr);
|
||||
Invalidation & setSourceId(const std::string &id);
|
||||
Invalidation & setObjectType(ObjectType type);
|
||||
Invalidation & setInvalidationType(InvalidationType type);
|
||||
|
||||
std::string getClassifier(ClassifierType type) const { return classifiers[type]; }
|
||||
Maybe<std::string, void> getStringMainAttr(const std::string &attr) const;
|
||||
Maybe<std::set<std::string>, void> getStringSetMainAttr(const std::string &attr) const;
|
||||
Maybe<std::string, void> getStringAttr(const std::string &attr) const;
|
||||
Maybe<std::set<std::string>, void> getStringSetAttr(const std::string &attr) const;
|
||||
std::vector<StrAttributes> getMainAttributes() const { return main_attributes; }
|
||||
std::vector<StrAttributes> getAttributes() const { return attributes; }
|
||||
const Maybe<std::string, void> & getSourceId() const { return source_id; }
|
||||
const Maybe<ObjectType, void> & getObjectType() const { return object_type; }
|
||||
InvalidationType getInvalidationType() const { return invalidation_type; }
|
||||
Maybe<std::string, void> getRegistrationID() const;
|
||||
|
||||
bool report(I_Intelligence_IS_V2 *interface) const;
|
||||
|
||||
@ -64,18 +85,16 @@ public:
|
||||
bool matches(const Invalidation &other) const;
|
||||
|
||||
private:
|
||||
bool hasMainAttr(const std::string &key, const std::string &value) const;
|
||||
bool hasAttr(const std::string &key, const std::string &value) const;
|
||||
bool attr_matches(const std::vector<StrAttributes> ¤t, const std::vector<StrAttributes> &other) const;
|
||||
|
||||
EnumArray<ClassifierType, std::string, 6> classifiers;
|
||||
std::map<std::string, std::string> string_main_attr;
|
||||
std::map<std::string, std::set<std::string>> set_string_main_attr;
|
||||
std::map<std::string, std::string> string_attr;
|
||||
std::map<std::string, std::set<std::string>> set_string_attr;
|
||||
std::vector<StrAttributes> main_attributes;
|
||||
std::vector<StrAttributes> attributes;
|
||||
Maybe<std::string, void> source_id;
|
||||
Maybe<ObjectType, void> object_type;
|
||||
InvalidationType invalidation_type = InvalidationType::ADD;
|
||||
Maybe<uint, void> listening_id;
|
||||
Maybe<std::string, void> registration_id;
|
||||
};
|
||||
|
||||
} // namespace Intelligence
|
||||
|
@ -34,9 +34,7 @@ public:
|
||||
bool isPagingActivated() const;
|
||||
Maybe<bool> isPagingFinished() const;
|
||||
Maybe<Intelligence_IS_V2::CursorState> getPagingStatus() const;
|
||||
bool loadJson(const std::string &json);
|
||||
Maybe<std::string> genJson() const;
|
||||
Maybe<std::string> getResponseFromFog() const;
|
||||
|
||||
size_t getSize() const { return queries.size(); }
|
||||
bool isBulk() const { return is_bulk; }
|
||||
|
@ -33,7 +33,7 @@ private:
|
||||
Maybe<Response> sendQueryObjectToLocalServer(bool is_primary_port);
|
||||
Maybe<Response> sendQueryMessage();
|
||||
Maybe<Response> sendMessage();
|
||||
Maybe<Response> createResponse();
|
||||
Maybe<Response> createResponse(const std::string &response_body);
|
||||
|
||||
IntelligenceRequest request;
|
||||
Flags<MessageConnectionConfig> conn_flags;
|
||||
|
@ -37,14 +37,12 @@ static const string registration_uri = "/api/v2/intelligence/invalidation/regist
|
||||
class I_InvalidationCallBack
|
||||
{
|
||||
public:
|
||||
virtual void performCallBacks(const Invalidation &invalidation) const = 0;
|
||||
virtual void performCallBacks(const Invalidation &invalidation, const string ®istration_id) const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~I_InvalidationCallBack() {}
|
||||
};
|
||||
|
||||
using MainAttrTypes = SerializableMultiMap<string, set<string>>;
|
||||
|
||||
static const map<string, Intelligence::ObjectType> object_names = {
|
||||
{ "asset", Intelligence::ObjectType::ASSET },
|
||||
{ "zone", Intelligence::ObjectType::ZONE },
|
||||
@ -54,6 +52,12 @@ static const map<string, Intelligence::ObjectType> object_names = {
|
||||
{ "shortLived", Intelligence::ObjectType::SHORTLIVED }
|
||||
};
|
||||
|
||||
static const map<string, Intelligence::InvalidationType> invalidation_type_names = {
|
||||
{ "add", Intelligence::InvalidationType::ADD },
|
||||
{ "delete", Intelligence::InvalidationType::DELETE },
|
||||
{ "update", Intelligence::InvalidationType::UPDATE }
|
||||
};
|
||||
|
||||
class InvalidationRegistration
|
||||
{
|
||||
public:
|
||||
@ -108,11 +112,22 @@ public:
|
||||
do {
|
||||
++running_id;
|
||||
} while (callbacks.find(running_id) != callbacks.end());
|
||||
auto invalidation_reg_id = invalidation.getRegistrationID();
|
||||
if (invalidation_reg_id.ok()) registration_id_to_cb[*invalidation_reg_id] = cb;
|
||||
callbacks.emplace(running_id, make_pair(invalidation, cb));
|
||||
return running_id;
|
||||
}
|
||||
|
||||
void erase(uint id) { callbacks.erase(id); }
|
||||
void
|
||||
erase(uint id)
|
||||
{
|
||||
auto actual_invalidation = callbacks.find(id);
|
||||
if (actual_invalidation == callbacks.end()) return;
|
||||
auto invalidation_reg_id = actual_invalidation->second.first.getRegistrationID();
|
||||
if (invalidation_reg_id.ok()) registration_id_to_cb.erase(*invalidation_reg_id);
|
||||
callbacks.erase(id);
|
||||
}
|
||||
|
||||
bool empty() const { return callbacks.empty(); }
|
||||
|
||||
InvalidationRegistration::RestCall
|
||||
@ -128,9 +143,13 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
performCallBacks(const Invalidation &invalidation) const override
|
||||
performCallBacks(const Invalidation &invalidation, const string ®istration_id) const override
|
||||
{
|
||||
dbgDebug(D_INTELLIGENCE) << "Looking for callbacks for invalidation " << invalidation.genObject();
|
||||
if (registration_id != "") {
|
||||
auto invalidation_cb = registration_id_to_cb.find(registration_id);
|
||||
if (invalidation_cb != registration_id_to_cb.end()) return invalidation_cb->second(invalidation);
|
||||
}
|
||||
for (auto ®isted_invalidation : callbacks) {
|
||||
dbgTrace(D_INTELLIGENCE) << "Checking against: " << registed_invalidation.second.first.genObject();
|
||||
performCallBacksImpl(invalidation, registed_invalidation.second);
|
||||
@ -140,20 +159,22 @@ public:
|
||||
private:
|
||||
void
|
||||
performCallBacksImpl(
|
||||
const Invalidation &actual_invalidation,
|
||||
const pair<Invalidation, function<void(const Invalidation &)>> &invalidation_and_cb
|
||||
const Invalidation &actual_invalidation,
|
||||
const pair<Invalidation, function<void(const Invalidation &)>> &invalidation_and_cb
|
||||
) const
|
||||
{
|
||||
auto ®istereed_invalidation = invalidation_and_cb.first;
|
||||
auto &cb = invalidation_and_cb.second;
|
||||
if (registereed_invalidation.matches(actual_invalidation)) cb(actual_invalidation);
|
||||
if (!registereed_invalidation.matches(actual_invalidation)) return;
|
||||
cb(actual_invalidation);
|
||||
}
|
||||
|
||||
map<uint, pair<Invalidation, function<void(const Invalidation &)>>> callbacks;
|
||||
map<string, function<void(const Invalidation &)>> registration_id_to_cb;
|
||||
uint running_id = 0;
|
||||
};
|
||||
|
||||
class RecieveInvalidation : public ServerRest
|
||||
class ReceiveInvalidation : public ServerRest
|
||||
{
|
||||
public:
|
||||
void
|
||||
@ -168,14 +189,14 @@ public:
|
||||
if (kind.isActive()) invalidation.setClassifier(ClassifierType::KIND, kind.get());
|
||||
|
||||
if (mainAttributes.isActive()) {
|
||||
auto strings = getMainAttr<string>();
|
||||
for (const auto &value : strings) {
|
||||
invalidation.setStringAttr(value.first, value.second);
|
||||
for (auto &vec_entry : mainAttributes.get()) {
|
||||
invalidation.addMainAttr(vec_entry);
|
||||
}
|
||||
}
|
||||
|
||||
auto string_sets = getMainAttr<set<string>>();
|
||||
for (const auto &value : string_sets) {
|
||||
invalidation.setStringSetAttr(value.first, value.second);
|
||||
if (attributes.isActive()) {
|
||||
for (auto &vec_entry : attributes.get()) {
|
||||
invalidation.addAttr(vec_entry);
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,25 +207,14 @@ public:
|
||||
|
||||
if (sourceId.isActive()) invalidation.setSourceId(sourceId.get());
|
||||
|
||||
string registration_id = "";
|
||||
if (invalidationRegistrationId.isActive()) registration_id = invalidationRegistrationId.get();
|
||||
|
||||
auto i_cb = Singleton::Consume<I_InvalidationCallBack>::from<InvalidationCallBack>();
|
||||
i_cb->performCallBacks(invalidation);
|
||||
i_cb->performCallBacks(invalidation, registration_id);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename ValType>
|
||||
map<string, ValType>
|
||||
getMainAttr()
|
||||
{
|
||||
map<string, ValType> res;
|
||||
|
||||
for (auto &vec_entry : mainAttributes.get()) {
|
||||
for (auto &attr : vec_entry.getMap<ValType>()) {
|
||||
res[attr.first] = attr.second;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
C2S_LABEL_PARAM(string, class_name, "class");
|
||||
C2S_OPTIONAL_PARAM(string, category);
|
||||
@ -214,7 +224,9 @@ private:
|
||||
C2S_OPTIONAL_PARAM(string, kind);
|
||||
C2S_OPTIONAL_PARAM(string, objectType);
|
||||
C2S_OPTIONAL_PARAM(string, sourceId);
|
||||
C2S_OPTIONAL_PARAM(vector<MainAttrTypes>, mainAttributes);
|
||||
C2S_OPTIONAL_PARAM(string, invalidationRegistrationId);
|
||||
C2S_OPTIONAL_PARAM(vector<StrAttributes>, mainAttributes);
|
||||
C2S_OPTIONAL_PARAM(vector<StrAttributes>, attributes);
|
||||
};
|
||||
|
||||
class IntelligenceComponentV2::Impl
|
||||
@ -238,7 +250,7 @@ public:
|
||||
);
|
||||
|
||||
auto rest_api = Singleton::Consume<I_RestApi>::by<IntelligenceComponentV2>();
|
||||
rest_api->addRestCall<RecieveInvalidation>(RestAction::SET, "new-invalidation/source/invalidation");
|
||||
rest_api->addRestCall<ReceiveInvalidation>(RestAction::SET, "new-invalidation/source/invalidation");
|
||||
}
|
||||
|
||||
bool
|
||||
@ -256,8 +268,9 @@ public:
|
||||
registerInvalidation(const Invalidation &invalidation, const function<void(const Invalidation &)> &cb) override
|
||||
{
|
||||
if (!invalidation.isLegalInvalidation()) return genError("Attempting to register invalid invalidation");
|
||||
if (!sendRegistration(invalidation)) return genError("Failed to register for invalidation");
|
||||
return invalidations.emplace(invalidation, cb);
|
||||
auto res = invalidations.emplace(invalidation, cb);
|
||||
sendReccurringInvalidationRegistration();
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -15,6 +15,98 @@ using namespace testing;
|
||||
|
||||
static const string invalidation_uri = "/api/v2/intelligence/invalidation";
|
||||
|
||||
|
||||
TEST(StringAttributesBasic, SettersAndGetters)
|
||||
{
|
||||
StrAttributes string_attributes;
|
||||
|
||||
EXPECT_TRUE(string_attributes.isEmpty());
|
||||
EXPECT_FALSE(string_attributes.getStringAttr("attr1").ok());
|
||||
EXPECT_FALSE(string_attributes.getStringSetAttr("attr2").ok());
|
||||
|
||||
set<string> vals = { "2", "3" };
|
||||
string_attributes
|
||||
.addStringAttr("attr1", "1")
|
||||
.addStringSetAttr("attr2", vals);
|
||||
|
||||
EXPECT_FALSE(string_attributes.isEmpty());
|
||||
EXPECT_EQ(string_attributes.getStringAttr("attr1").unpack(), "1");
|
||||
EXPECT_EQ(string_attributes.getStringSetAttr("attr2").unpack(), vals);
|
||||
}
|
||||
|
||||
TEST(StringAttributesBasic, attr_schema)
|
||||
{
|
||||
set<string> vals = { "2", "3" };
|
||||
auto string_attributes = StrAttributes()
|
||||
.addStringAttr("attr1", "1")
|
||||
.addStringSetAttr("attr2", vals);
|
||||
stringstream ss;
|
||||
string_attributes.performOutputingSchema(ss, 0);
|
||||
string expected_schema =
|
||||
"{\n"
|
||||
" \"attr1\": \"1\",\n"
|
||||
" \"attr2\": [\n"
|
||||
" \"2\",\n"
|
||||
" \"3\"\n"
|
||||
" ]\n"
|
||||
"}";
|
||||
EXPECT_EQ(ss.str(), expected_schema);
|
||||
}
|
||||
|
||||
TEST(StringAttributesBasic, Matching)
|
||||
{
|
||||
set<string> vals = { "2", "3" };
|
||||
auto base_string_attributes = StrAttributes()
|
||||
.addStringAttr("attr1", "1")
|
||||
.addStringAttr("attr2", "2")
|
||||
.addStringAttr("attr3", "3")
|
||||
.addStringSetAttr("attr4", vals);
|
||||
|
||||
auto matching_string_attributes = StrAttributes()
|
||||
.addStringAttr("attr1", "1")
|
||||
.addStringAttr("attr2", "2")
|
||||
.addStringAttr("attr3", "3")
|
||||
.addStringSetAttr("attr4", vals)
|
||||
.addStringAttr("attr5", "6")
|
||||
.addStringSetAttr("attr6", vals);
|
||||
|
||||
EXPECT_TRUE(base_string_attributes.matches(matching_string_attributes));
|
||||
|
||||
auto not_matching_string_attributes = StrAttributes()
|
||||
.addStringAttr("attr1", "1")
|
||||
.addStringAttr("attr2", "2")
|
||||
.addStringSetAttr("attr4", vals)
|
||||
.addStringAttr("attr3", "6");
|
||||
|
||||
EXPECT_FALSE(base_string_attributes.matches(not_matching_string_attributes));
|
||||
|
||||
auto missing_attr_string_attributes = StrAttributes()
|
||||
.addStringAttr("attr1", "1")
|
||||
.addStringSetAttr("attr2", vals);
|
||||
|
||||
EXPECT_FALSE(base_string_attributes.matches(missing_attr_string_attributes));
|
||||
|
||||
set<string> vals2 = { "1", "5", "2", "3" };
|
||||
auto has_extra_value_string_attributes = StrAttributes()
|
||||
.addStringAttr("attr1", "1")
|
||||
.addStringAttr("attr2", "2")
|
||||
.addStringAttr("attr3", "3")
|
||||
.addStringSetAttr("attr4", vals2);
|
||||
|
||||
EXPECT_TRUE(base_string_attributes.matches(has_extra_value_string_attributes));
|
||||
}
|
||||
|
||||
TEST(StringAttributesBasic, genObject)
|
||||
{
|
||||
set<string> vals = { "2", "3" };
|
||||
auto string_attributes = StrAttributes()
|
||||
.addStringAttr("attr1", "1")
|
||||
.addStringSetAttr("attr2", vals);
|
||||
|
||||
string expected_json = "{ \"attr1\": \"1\", \"attr2\": [ \"2\", \"3\" ] }";
|
||||
EXPECT_EQ(string_attributes.genObject().unpack(), expected_json);
|
||||
}
|
||||
|
||||
TEST(InvalidationBasic, SettersAndGetters)
|
||||
{
|
||||
Invalidation invalidation("aaa");
|
||||
@ -27,33 +119,37 @@ TEST(InvalidationBasic, SettersAndGetters)
|
||||
EXPECT_EQ(invalidation.getClassifier(ClassifierType::KIND), "");
|
||||
EXPECT_EQ(invalidation.getInvalidationType(), InvalidationType::ADD);
|
||||
|
||||
EXPECT_FALSE(invalidation.getStringMainAttr("main_attr1").ok());
|
||||
EXPECT_FALSE(invalidation.getStringSetMainAttr("main_attr2").ok());
|
||||
EXPECT_FALSE(invalidation.getStringAttr("attr1").ok());
|
||||
EXPECT_FALSE(invalidation.getStringSetAttr("attr2").ok());
|
||||
EXPECT_TRUE(invalidation.getMainAttributes().empty());
|
||||
EXPECT_TRUE(invalidation.getAttributes().empty());
|
||||
EXPECT_FALSE(invalidation.getSourceId().ok());
|
||||
EXPECT_FALSE(invalidation.getObjectType().ok());
|
||||
|
||||
set<string> main_vals = { "2", "3" };
|
||||
set<string> vals = { "5", "6" };
|
||||
|
||||
auto main_attr = StrAttributes()
|
||||
.addStringAttr("main_attr1", "1")
|
||||
.addStringSetAttr("main_attr2", main_vals);
|
||||
|
||||
auto attr = StrAttributes()
|
||||
.addStringAttr("attr1", "4")
|
||||
.addStringSetAttr("attr2", vals);
|
||||
|
||||
invalidation
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setStringAttr("main_attr1", "1")
|
||||
.setStringSetAttr("main_attr2", main_vals)
|
||||
.setStringAttr("attr1", "4", false)
|
||||
.setStringSetAttr("attr2", vals, false)
|
||||
.addMainAttr(main_attr)
|
||||
.addAttr(attr)
|
||||
.setSourceId("id")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET)
|
||||
.setInvalidationType(InvalidationType::DELETE);
|
||||
|
||||
EXPECT_EQ(invalidation.getClassifier(ClassifierType::CATEGORY), "bbb");
|
||||
EXPECT_EQ(invalidation.getClassifier(ClassifierType::FAMILY), "ccc");
|
||||
EXPECT_EQ(invalidation.getStringMainAttr("main_attr1").unpack(), "1");
|
||||
EXPECT_EQ(invalidation.getStringSetMainAttr("main_attr2").unpack(), main_vals);
|
||||
EXPECT_EQ(invalidation.getStringAttr("attr1").unpack(), "4");
|
||||
EXPECT_EQ(invalidation.getStringSetAttr("attr2").unpack(), vals);
|
||||
EXPECT_EQ(invalidation.getMainAttributes().begin()->getStringAttr("main_attr1").unpack(), "1");
|
||||
EXPECT_EQ(invalidation.getMainAttributes().begin()->getStringSetAttr("main_attr2").unpack(), main_vals);
|
||||
EXPECT_EQ(invalidation.getAttributes().begin()->getStringAttr("attr1").unpack(), "4");
|
||||
EXPECT_EQ(invalidation.getAttributes().begin()->getStringSetAttr("attr2").unpack(), vals);
|
||||
EXPECT_EQ(invalidation.getSourceId().unpack(), "id");
|
||||
EXPECT_EQ(invalidation.getObjectType().unpack(), Intelligence::ObjectType::ASSET);
|
||||
EXPECT_EQ(invalidation.getInvalidationType(), InvalidationType::DELETE);
|
||||
@ -63,84 +159,87 @@ TEST(InvalidationBasic, Matching)
|
||||
{
|
||||
set<string> main_vals = { "2", "3" };
|
||||
set<string> vals = { "5", "6" };
|
||||
|
||||
auto main_attr = StrAttributes()
|
||||
.addStringAttr("main_attr1", "1")
|
||||
.addStringSetAttr("main_attr2", main_vals);
|
||||
|
||||
auto attr = StrAttributes()
|
||||
.addStringAttr("attr1", "4")
|
||||
.addStringSetAttr("attr2", vals);
|
||||
|
||||
auto base_invalidation = Invalidation("aaa")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setStringAttr("main_attr1", "1")
|
||||
.setStringSetAttr("main_attr2", main_vals)
|
||||
.setStringAttr("attr1", "4", false)
|
||||
.setStringSetAttr("attr2", vals, false);
|
||||
.addMainAttr(main_attr)
|
||||
.addAttr(attr);
|
||||
|
||||
auto matching_main_attr = StrAttributes()
|
||||
.addStringAttr("main_attr1", "1")
|
||||
.addStringSetAttr("main_attr2", main_vals)
|
||||
.addStringAttr("main_attr3", "6");
|
||||
|
||||
auto matching_attr = StrAttributes()
|
||||
.addStringAttr("attr1", "4")
|
||||
.addStringSetAttr("attr2", vals)
|
||||
.addStringAttr("attr3", "7");
|
||||
|
||||
auto matching_invalidation = Invalidation("aaa")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::GROUP, "ddd")
|
||||
.setStringAttr("main_attr1", "1")
|
||||
.setStringSetAttr("main_attr2", main_vals)
|
||||
.setStringAttr("attr1", "4", false)
|
||||
.setStringSetAttr("attr2", vals, false)
|
||||
.setStringAttr("main_attr3", "6")
|
||||
.setStringAttr("attr3", "7", false)
|
||||
.addMainAttr(matching_main_attr)
|
||||
.addAttr(matching_attr)
|
||||
.setSourceId("id")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET)
|
||||
.setInvalidationType(InvalidationType::ADD);
|
||||
|
||||
EXPECT_TRUE(base_invalidation.matches(matching_invalidation));
|
||||
|
||||
auto not_matching_invalidation_type = Invalidation("aaa")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::GROUP, "ddd")
|
||||
.setStringAttr("main_attr1", "1")
|
||||
.setStringSetAttr("main_attr2", main_vals)
|
||||
.setSourceId("id")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET)
|
||||
.setInvalidationType(InvalidationType::DELETE);
|
||||
|
||||
EXPECT_FALSE(base_invalidation.matches(not_matching_invalidation_type));
|
||||
auto missing_attr_main = StrAttributes()
|
||||
.addStringAttr("main_attr1", "1")
|
||||
.addStringAttr("main_attr2", "2")
|
||||
.addStringAttr("main_attr3", "6");
|
||||
|
||||
auto missing_attr_invalidation_main = Invalidation("aaa")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::GROUP, "ddd")
|
||||
.setStringAttr("main_attr1", "1")
|
||||
.setStringAttr("main_attr2", "2")
|
||||
.setStringAttr("main_attr3", "6")
|
||||
.setStringAttr("attr1", "4", false)
|
||||
.setStringSetAttr("attr2", vals, false)
|
||||
.setStringAttr("attr3", "7", false)
|
||||
.addMainAttr(missing_attr_main)
|
||||
.addAttr(matching_attr)
|
||||
.setSourceId("id")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
EXPECT_FALSE(base_invalidation.matches(missing_attr_invalidation_main));
|
||||
|
||||
auto missing_attr = StrAttributes()
|
||||
.addStringAttr("attr1", "4")
|
||||
.addStringAttr("attr2", "2")
|
||||
.addStringAttr("attr3", "7");
|
||||
|
||||
auto missing_attr_invalidation = Invalidation("aaa")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::GROUP, "ddd")
|
||||
.setStringAttr("main_attr1", "1")
|
||||
.setStringSetAttr("main_attr2", main_vals)
|
||||
.setStringAttr("main_attr3", "6")
|
||||
.setStringAttr("attr1", "4", false)
|
||||
.setStringAttr("attr2", "2", false)
|
||||
.setStringAttr("attr3", "7", false)
|
||||
.addMainAttr(matching_main_attr)
|
||||
.addAttr(missing_attr)
|
||||
.setSourceId("id")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
EXPECT_FALSE(base_invalidation.matches(missing_attr_invalidation));
|
||||
|
||||
set<string> vals2 = { "1", "5" };
|
||||
auto extra_value_main_attr = StrAttributes()
|
||||
.addStringSetAttr("main_attr1", vals2)
|
||||
.addStringSetAttr("main_attr2", main_vals)
|
||||
.addStringAttr("main_attr3", "6");
|
||||
|
||||
auto has_extra_value_invalidation = Invalidation("aaa")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::GROUP, "ddd")
|
||||
.setStringSetAttr("main_attr1", vals2)
|
||||
.setStringSetAttr("main_attr2", main_vals)
|
||||
.setStringAttr("main_attr3", "6")
|
||||
.setStringAttr("attr1", "4", false)
|
||||
.setStringSetAttr("attr2", vals, false)
|
||||
.setStringAttr("attr3", "7", false)
|
||||
.addMainAttr(extra_value_main_attr)
|
||||
.addAttr(matching_attr)
|
||||
.setSourceId("id")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
@ -180,6 +279,8 @@ public:
|
||||
conf.preload();
|
||||
intelligence.preload();
|
||||
intelligence.init();
|
||||
main_attr.addStringAttr("attr2", "2");
|
||||
attr.addStringAttr("attr3", "3");
|
||||
}
|
||||
|
||||
bool
|
||||
@ -189,6 +290,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
StrAttributes main_attr;
|
||||
StrAttributes attr;
|
||||
StrictMock<MockMessaging> messaging_mock;
|
||||
StrictMock<MockMainLoop> mock_ml;
|
||||
NiceMock<MockTimeGet> mock_time;
|
||||
@ -208,7 +311,7 @@ public:
|
||||
TEST_F(IntelligenceInvalidation, sending_incomplete_invalidation)
|
||||
{
|
||||
auto invalidation = Invalidation("aaa")
|
||||
.setStringAttr("attr2", "2")
|
||||
.addMainAttr(main_attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
@ -219,8 +322,8 @@ TEST_F(IntelligenceInvalidation, sending_incomplete_invalidation)
|
||||
TEST_F(IntelligenceInvalidation, sending_public_invalidation)
|
||||
{
|
||||
auto invalidation = Invalidation("aaa")
|
||||
.setStringAttr("attr2", "2")
|
||||
.setStringAttr("attr3", "3", false)
|
||||
.addMainAttr(main_attr)
|
||||
.addAttr(attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
@ -254,11 +357,51 @@ TEST_F(IntelligenceInvalidation, sending_public_invalidation)
|
||||
EXPECT_FALSE(md.getConnectionFlags().isSet(MessageConnectionConfig::UNSECURE_CONN));
|
||||
}
|
||||
|
||||
TEST_F(IntelligenceInvalidation, multiple_assets_invalidation)
|
||||
{
|
||||
auto main_attr_2 = StrAttributes()
|
||||
.addStringAttr("attr2", "22")
|
||||
.addStringSetAttr("attr3", {"33", "44"});
|
||||
|
||||
auto invalidation = Invalidation("aaa")
|
||||
.addMainAttr(main_attr)
|
||||
.addMainAttr(main_attr_2)
|
||||
.addAttr(attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
string invalidation_json;
|
||||
EXPECT_CALL(
|
||||
messaging_mock,
|
||||
sendSyncMessage(HTTPMethod::POST, invalidation_uri, _, MessageCategory::INTELLIGENCE, _)
|
||||
).WillOnce(DoAll(
|
||||
SaveArg<2>(&invalidation_json),
|
||||
Return(HTTPResponse(HTTPStatusCode::HTTP_OK, ""))
|
||||
));
|
||||
|
||||
EXPECT_TRUE(invalidation.report(i_intelligence));
|
||||
|
||||
string expected_json =
|
||||
"{ \"invalidations\": [ { "
|
||||
"\"class\": \"aaa\", "
|
||||
"\"category\": \"bbb\", "
|
||||
"\"family\": \"ccc\", "
|
||||
"\"objectType\": \"asset\", "
|
||||
"\"invalidationType\": \"add\", "
|
||||
"\"sourceId\": \"id\", "
|
||||
"\"mainAttributes\": [ { \"attr2\": \"2\" }, { \"attr2\": \"22\", \"attr3\": [ \"33\", \"44\" ] } ], "
|
||||
"\"attributes\": [ { \"attr3\": \"3\" } ]"
|
||||
" } ] }";
|
||||
EXPECT_EQ(invalidation_json, expected_json);
|
||||
}
|
||||
|
||||
TEST_F(IntelligenceInvalidation, sending_private_invalidation)
|
||||
{
|
||||
auto invalidation = Invalidation("aaa")
|
||||
.setStringAttr("attr2", "2")
|
||||
.setStringAttr("attr3", "3", false)
|
||||
.addMainAttr(main_attr)
|
||||
.addAttr(attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
@ -319,10 +462,10 @@ TEST_F(IntelligenceInvalidation, register_for_invalidation)
|
||||
configuration << "}";
|
||||
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(configuration);
|
||||
|
||||
set<string> vals = { "11", "55", "22" };
|
||||
|
||||
auto invalidation = Invalidation("aaa")
|
||||
.setStringAttr("attr2", "2")
|
||||
.setStringSetAttr("attr3", vals, false)
|
||||
.addMainAttr(main_attr)
|
||||
.addAttr(attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
@ -344,10 +487,89 @@ TEST_F(IntelligenceInvalidation, register_for_invalidation)
|
||||
EXPECT_THAT(body, HasSubstr("\"url\": \"http://127.0.0.1:7000/set-new-invalidation\""));
|
||||
EXPECT_THAT(body, HasSubstr("\"apiVersion\": \"v2\", \"communicationType\": \"sync\""));
|
||||
EXPECT_THAT(body, HasSubstr("\"mainAttributes\": [ { \"attr2\": \"2\" } ]"));
|
||||
EXPECT_THAT(body, HasSubstr("\"attributes\": [ { \"attr3\": [ \"11\", \"22\", \"55\" ] } ]"));
|
||||
EXPECT_THAT(body, HasSubstr("\"attributes\": [ { \"attr3\": \"3\" } ]"));
|
||||
EXPECT_TRUE(md.getConnectionFlags().isSet(MessageConnectionConfig::UNSECURE_CONN));
|
||||
}
|
||||
|
||||
TEST_F(IntelligenceInvalidation, register_for_multiple_assets_invalidation)
|
||||
{
|
||||
stringstream configuration;
|
||||
configuration << "{";
|
||||
configuration << " \"agentSettings\":[";
|
||||
configuration << " {\"key\":\"agent.config.useLocalIntelligence\",\"id\":\"id1\",\"value\":\"true\"}";
|
||||
configuration << " ],";
|
||||
configuration << " \"intelligence\":{";
|
||||
configuration << " \"local intelligence server ip\":\"127.0.0.1\",";
|
||||
configuration << " \"local intelligence server primary port\":9090";
|
||||
configuration << " }";
|
||||
configuration << "}";
|
||||
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(configuration);
|
||||
|
||||
auto multiple_assets_main_attr1 = StrAttributes()
|
||||
.addStringAttr("attr2", "22");
|
||||
auto multiple_assets_main_attr2 = StrAttributes()
|
||||
.addStringAttr("attr2", "222");
|
||||
auto multiple_assets_main_attr3 = StrAttributes()
|
||||
.addStringAttr("attr2", "2222")
|
||||
.addStringSetAttr("attr3", {"3333", "4444"});
|
||||
auto invalidation = Invalidation("aaa")
|
||||
.addMainAttr(multiple_assets_main_attr1)
|
||||
.addMainAttr(multiple_assets_main_attr2)
|
||||
.addMainAttr(multiple_assets_main_attr3)
|
||||
.addAttr(attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
string body;
|
||||
EXPECT_CALL(
|
||||
messaging_mock,
|
||||
sendSyncMessage(_, "/api/v2/intelligence/invalidation/register", _, _, _)
|
||||
).WillOnce(DoAll(
|
||||
SaveArg<2>(&body),
|
||||
Return(HTTPResponse(HTTPStatusCode::HTTP_OK, ""))
|
||||
));
|
||||
|
||||
EXPECT_NE(i_intelligence->registerInvalidation(invalidation, callback), 0);
|
||||
|
||||
EXPECT_THAT(
|
||||
body,
|
||||
HasSubstr(
|
||||
"\"mainAttributes\": [ "
|
||||
"{ \"attr2\": \"22\" }, "
|
||||
"{ \"attr2\": \"222\" }, "
|
||||
"{ \"attr2\": \"2222\", \"attr3\": [ \"3333\", \"4444\" ] } "
|
||||
"]"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
TEST_F(IntelligenceInvalidation, register_incomplit_invalidation)
|
||||
{
|
||||
stringstream configuration;
|
||||
configuration << "{";
|
||||
configuration << " \"agentSettings\":[";
|
||||
configuration << " {\"key\":\"agent.config.useLocalIntelligence\",\"id\":\"id1\",\"value\":\"true\"}";
|
||||
configuration << " ],";
|
||||
configuration << " \"intelligence\":{";
|
||||
configuration << " \"local intelligence server ip\":\"127.0.0.1\",";
|
||||
configuration << " \"local intelligence server primary port\":9090";
|
||||
configuration << " }";
|
||||
configuration << "}";
|
||||
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(configuration);
|
||||
|
||||
|
||||
auto invalidation = Invalidation("aaa")
|
||||
.addMainAttr(main_attr)
|
||||
.addAttr(attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
EXPECT_FALSE(i_intelligence->registerInvalidation(invalidation, callback).ok());
|
||||
}
|
||||
|
||||
TEST_F(IntelligenceInvalidation, invalidation_callback)
|
||||
{
|
||||
stringstream configuration;
|
||||
@ -363,7 +585,7 @@ TEST_F(IntelligenceInvalidation, invalidation_callback)
|
||||
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(configuration);
|
||||
|
||||
auto invalidation = Invalidation("aaa")
|
||||
.setStringAttr("attr2", "2")
|
||||
.addMainAttr(main_attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
@ -377,8 +599,10 @@ TEST_F(IntelligenceInvalidation, invalidation_callback)
|
||||
EXPECT_NE(i_intelligence->registerInvalidation(invalidation, callback), 0);
|
||||
|
||||
set<string> vals = { "1", "5", "2" };
|
||||
auto test_main_attr = StrAttributes()
|
||||
.addStringSetAttr("attr2", vals);
|
||||
auto invalidation2 = Invalidation("aaa")
|
||||
.setStringSetAttr("attr2", vals)
|
||||
.addMainAttr(test_main_attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
@ -389,7 +613,7 @@ TEST_F(IntelligenceInvalidation, invalidation_callback)
|
||||
mock_invalidation->performRestCall(json);
|
||||
|
||||
EXPECT_EQ(recieved_invalidations.size(), 1);
|
||||
EXPECT_EQ(recieved_invalidations[0].getStringSetMainAttr("attr2").unpack(), vals);
|
||||
EXPECT_EQ(recieved_invalidations[0].getMainAttributes().begin()->getStringSetAttr("attr2").unpack(), vals);
|
||||
}
|
||||
|
||||
TEST_F(IntelligenceInvalidation, delete_invalidation_callback)
|
||||
@ -407,7 +631,7 @@ TEST_F(IntelligenceInvalidation, delete_invalidation_callback)
|
||||
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(configuration);
|
||||
|
||||
auto invalidation = Invalidation("aaa")
|
||||
.setStringAttr("attr2", "2")
|
||||
.addMainAttr(main_attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
@ -421,9 +645,8 @@ TEST_F(IntelligenceInvalidation, delete_invalidation_callback)
|
||||
auto callback_id = i_intelligence->registerInvalidation(invalidation, callback);
|
||||
i_intelligence->unregisterInvalidation(*callback_id);
|
||||
|
||||
set<string> vals = { "1", "5", "2" };
|
||||
auto invalidation2 = Invalidation("aaa")
|
||||
.setStringSetAttr("attr2", vals)
|
||||
.addMainAttr(main_attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
@ -451,7 +674,7 @@ TEST_F(IntelligenceInvalidation, invalidation_short_handling)
|
||||
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(configuration);
|
||||
|
||||
auto invalidation = Invalidation("aaa")
|
||||
.setStringAttr("attr2", "2")
|
||||
.addMainAttr(main_attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
@ -466,9 +689,8 @@ TEST_F(IntelligenceInvalidation, invalidation_short_handling)
|
||||
|
||||
invalidation.stopListening(i_intelligence);
|
||||
|
||||
set<string> vals = { "1", "5", "2" };
|
||||
auto invalidation2 = Invalidation("aaa")
|
||||
.setStringSetAttr("attr2", vals)
|
||||
.addMainAttr(main_attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
@ -498,7 +720,7 @@ TEST_F(IntelligenceInvalidation, routine_registration)
|
||||
routine();
|
||||
|
||||
auto invalidation = Invalidation("aaa")
|
||||
.setStringAttr("attr2", "2")
|
||||
.addMainAttr(main_attr)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
@ -526,3 +748,191 @@ TEST_F(IntelligenceInvalidation, routine_registration)
|
||||
EXPECT_THAT(body, HasSubstr("\"apiVersion\": \"v2\", \"communicationType\": \"sync\""));
|
||||
EXPECT_THAT(body, HasSubstr("\"mainAttributes\": [ { \"attr2\": \"2\" } ]"));
|
||||
}
|
||||
|
||||
TEST_F(IntelligenceInvalidation, invalidation_flow_with_multiple_assets)
|
||||
{
|
||||
stringstream configuration;
|
||||
configuration << "{";
|
||||
configuration << " \"agentSettings\":[";
|
||||
configuration << " {\"key\":\"agent.config.useLocalIntelligence\",\"id\":\"id1\",\"value\":\"true\"}";
|
||||
configuration << " ],";
|
||||
configuration << " \"intelligence\":{";
|
||||
configuration << " \"local intelligence server ip\":\"127.0.0.1\",";
|
||||
configuration << " \"local intelligence server primary port\":9090";
|
||||
configuration << " }";
|
||||
configuration << "}";
|
||||
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(configuration);
|
||||
|
||||
auto base_main_attr2 = StrAttributes()
|
||||
.addStringAttr("attr3", "3");
|
||||
auto invalidation_to_register = Invalidation("aaa")
|
||||
.addMainAttr(main_attr)
|
||||
.addMainAttr(base_main_attr2)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
EXPECT_CALL(
|
||||
messaging_mock,
|
||||
sendSyncMessage(_, "/api/v2/intelligence/invalidation/register", _, _, _)
|
||||
).WillOnce(Return(HTTPResponse(HTTPStatusCode::HTTP_OK, "")));
|
||||
|
||||
invalidation_to_register.startListening(i_intelligence, callback);
|
||||
auto stop_listening = make_scope_exit([&] { invalidation_to_register.stopListening(i_intelligence); });
|
||||
|
||||
auto not_matching_main_attributes = StrAttributes()
|
||||
.addStringAttr("attr3", "4");
|
||||
|
||||
auto not_matching_invalidation = Invalidation("aaa")
|
||||
.addMainAttr(not_matching_main_attributes)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
stringstream json1;
|
||||
json1 << not_matching_invalidation.genObject();
|
||||
mock_invalidation->performRestCall(json1);
|
||||
|
||||
EXPECT_EQ(recieved_invalidations.size(), 0);
|
||||
|
||||
auto matching_second_main_attribute = StrAttributes()
|
||||
.addStringAttr("attr3", "3");
|
||||
|
||||
auto matching_invalidation = Invalidation("aaa")
|
||||
.addMainAttr(matching_second_main_attribute)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
stringstream json2;
|
||||
json2 << matching_invalidation.genObject();
|
||||
mock_invalidation->performRestCall(json2);
|
||||
|
||||
EXPECT_EQ(recieved_invalidations.size(), 1);
|
||||
}
|
||||
|
||||
TEST_F(IntelligenceInvalidation, invalidation_cb_match_2_registred_assets)
|
||||
{
|
||||
stringstream configuration;
|
||||
configuration << "{";
|
||||
configuration << " \"agentSettings\":[";
|
||||
configuration << " {\"key\":\"agent.config.useLocalIntelligence\",\"id\":\"id1\",\"value\":\"true\"}";
|
||||
configuration << " ],";
|
||||
configuration << " \"intelligence\":{";
|
||||
configuration << " \"local intelligence server ip\":\"127.0.0.1\",";
|
||||
configuration << " \"local intelligence server primary port\":9090";
|
||||
configuration << " }";
|
||||
configuration << "}";
|
||||
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(configuration);
|
||||
|
||||
auto base_main_attr2 = StrAttributes()
|
||||
.addStringAttr("attr3", "3");
|
||||
auto invalidation_to_register = Invalidation("aaa")
|
||||
.addMainAttr(main_attr)
|
||||
.addMainAttr(base_main_attr2)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
EXPECT_CALL(
|
||||
messaging_mock,
|
||||
sendSyncMessage(_, "/api/v2/intelligence/invalidation/register", _, _, _)
|
||||
).Times(2).WillRepeatedly(Return(HTTPResponse(HTTPStatusCode::HTTP_OK, "")));
|
||||
|
||||
invalidation_to_register.startListening(i_intelligence, callback);
|
||||
auto stop_listening = make_scope_exit([&] { invalidation_to_register.stopListening(i_intelligence); });
|
||||
|
||||
auto matching_second_main_attribute = StrAttributes()
|
||||
.addStringAttr("attr3", "3");
|
||||
|
||||
auto matching_invalidation = Invalidation("aaa")
|
||||
.addMainAttr(matching_second_main_attribute)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
|
||||
auto invalidation_2_to_register = Invalidation("aaa")
|
||||
.addMainAttr(base_main_attr2)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
invalidation_2_to_register.startListening(i_intelligence, callback);
|
||||
auto stop_listening_2 = make_scope_exit([&] { invalidation_2_to_register.stopListening(i_intelligence); });
|
||||
|
||||
stringstream json;
|
||||
json << matching_invalidation.genObject();
|
||||
mock_invalidation->performRestCall(json);
|
||||
|
||||
EXPECT_EQ(recieved_invalidations.size(), 2);
|
||||
}
|
||||
|
||||
TEST_F(IntelligenceInvalidation, invalidation_cb_match_by_registration_id)
|
||||
{
|
||||
stringstream configuration;
|
||||
configuration << "{";
|
||||
configuration << " \"agentSettings\":[";
|
||||
configuration << " {\"key\":\"agent.config.useLocalIntelligence\",\"id\":\"id1\",\"value\":\"true\"}";
|
||||
configuration << " ],";
|
||||
configuration << " \"intelligence\":{";
|
||||
configuration << " \"local intelligence server ip\":\"127.0.0.1\",";
|
||||
configuration << " \"local intelligence server primary port\":9090";
|
||||
configuration << " }";
|
||||
configuration << "}";
|
||||
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(configuration);
|
||||
|
||||
auto base_main_attr2 = StrAttributes()
|
||||
.addStringAttr("attr3", "3");
|
||||
auto invalidation_to_register = Invalidation("aaa")
|
||||
.addMainAttr(main_attr)
|
||||
.addMainAttr(base_main_attr2)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
EXPECT_CALL(
|
||||
messaging_mock,
|
||||
sendSyncMessage(_, "/api/v2/intelligence/invalidation/register", _, _, _)
|
||||
).Times(2).WillRepeatedly(Return(HTTPResponse(HTTPStatusCode::HTTP_OK, "")));
|
||||
|
||||
invalidation_to_register.startListening(i_intelligence, callback);
|
||||
auto stop_listening = make_scope_exit([&] { invalidation_to_register.stopListening(i_intelligence); });
|
||||
|
||||
auto matching_second_main_attribute = StrAttributes()
|
||||
.addStringAttr("attr3", "3");
|
||||
|
||||
auto matching_invalidation = Invalidation("aaa")
|
||||
.addMainAttr(matching_second_main_attribute)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
|
||||
auto invalidation_2_to_register = Invalidation("aaa")
|
||||
.addMainAttr(base_main_attr2)
|
||||
.setSourceId("id")
|
||||
.setClassifier(ClassifierType::FAMILY, "ccc")
|
||||
.setClassifier(ClassifierType::CATEGORY, "bbb")
|
||||
.setObjectType(Intelligence::ObjectType::ASSET);
|
||||
|
||||
invalidation_2_to_register.startListening(i_intelligence, callback);
|
||||
auto registration_id = invalidation_2_to_register.getRegistrationID();
|
||||
auto stop_listening_2 = make_scope_exit([&] { invalidation_2_to_register.stopListening(i_intelligence); });
|
||||
|
||||
string modifiedJsonString = matching_invalidation.genObject().substr(2);
|
||||
stringstream json;
|
||||
json << "{ \"invalidationRegistrationId\": \""<< *registration_id << "\", " << modifiedJsonString;
|
||||
cout << json.str() << endl;
|
||||
mock_invalidation->performRestCall(json);
|
||||
|
||||
EXPECT_EQ(recieved_invalidations.size(), 1);
|
||||
}
|
||||
|
@ -113,16 +113,3 @@ IntelligenceRequest::genJson() const
|
||||
|
||||
return str_stream.str();
|
||||
}
|
||||
|
||||
bool
|
||||
IntelligenceRequest::loadJson(const string &json)
|
||||
{
|
||||
response_from_fog = json;
|
||||
return true;
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
IntelligenceRequest::getResponseFromFog() const
|
||||
{
|
||||
return response_from_fog;
|
||||
}
|
||||
|
@ -140,64 +140,49 @@ Sender::sendQueryMessage()
|
||||
Maybe<Response>
|
||||
Sender::sendMessage()
|
||||
{
|
||||
if (server_ip.ok() || server_port.ok()) {
|
||||
if (!server_ip.ok()) return genError("Can't send intelligence request. Server ip wasn't set");
|
||||
if (!server_port.ok()) return genError("Can't send intelligence request. Server port wasn't set");
|
||||
} else if (!server_ip.ok() && !server_port.ok()) {
|
||||
auto req_status = i_message->sendSyncMessage(
|
||||
HTTPMethod::POST,
|
||||
request.isBulk() ? queries_uri : query_uri,
|
||||
request,
|
||||
MessageCategory::INTELLIGENCE
|
||||
);
|
||||
if (req_status.ok()) {
|
||||
return createResponse();
|
||||
};
|
||||
auto response_error = req_status.getErr().toString();
|
||||
dbgWarning(D_INTELLIGENCE) << "Failed to send intelligence request. Error:" << response_error;
|
||||
return genError(
|
||||
"Failed to send intelligence request. "
|
||||
+ req_status.getErr().getBody()
|
||||
+ " "
|
||||
+ req_status.getErr().toString()
|
||||
);
|
||||
if (server_port.ok() && !server_ip.ok()) return genError("Can't send intelligence request. Server ip invalid");
|
||||
if (server_ip.ok() && !server_port.ok()) return genError("Can't send intelligence request. Server port invalid");
|
||||
auto req_md = server_ip.ok() ? MessageMetadata(*server_ip, *server_port, conn_flags) : MessageMetadata();
|
||||
|
||||
if (server_ip.ok()) {
|
||||
dbgTrace(D_INTELLIGENCE)
|
||||
<< "Sending intelligence request with IP: "
|
||||
<< *server_ip
|
||||
<< " port: "
|
||||
<< *server_port
|
||||
<< " query_uri: "
|
||||
<< (request.isBulk() ? queries_uri : query_uri);
|
||||
}
|
||||
|
||||
dbgTrace(D_INTELLIGENCE)
|
||||
<< "Sending intelligence request with IP: "
|
||||
<< *server_ip
|
||||
<< " port: "
|
||||
<< *server_port
|
||||
<< " query_uri: "
|
||||
<< (request.isBulk() ? queries_uri : query_uri);
|
||||
|
||||
MessageMetadata req_md(*server_ip, *server_port, conn_flags);
|
||||
auto req_status = i_message->sendSyncMessage(
|
||||
auto json_body = request.genJson();
|
||||
if (!json_body.ok()) return json_body.passErr();
|
||||
auto req_data = i_message->sendSyncMessage(
|
||||
HTTPMethod::POST,
|
||||
request.isBulk() ? queries_uri : query_uri,
|
||||
request,
|
||||
*json_body,
|
||||
MessageCategory::INTELLIGENCE,
|
||||
req_md
|
||||
);
|
||||
if (!req_status.ok()) {
|
||||
auto response_error = req_status.getErr().toString();
|
||||
if (!req_data.ok()) {
|
||||
auto response_error = req_data.getErr().toString();
|
||||
dbgWarning(D_INTELLIGENCE) << "Failed to send intelligence request. Error:" << response_error;
|
||||
return genError(
|
||||
"Failed to send intelligence request. "
|
||||
+ req_status.getErr().getBody()
|
||||
+ req_data.getErr().getBody()
|
||||
+ " "
|
||||
+ req_status.getErr().toString()
|
||||
+ req_data.getErr().toString()
|
||||
);
|
||||
};
|
||||
return createResponse();
|
||||
} else if (req_data->getHTTPStatusCode() != HTTPStatusCode::HTTP_OK) {
|
||||
return genError("Intelligence response is invalid. " + req_data->toString());
|
||||
}
|
||||
|
||||
return createResponse(req_data->getBody());
|
||||
}
|
||||
|
||||
Maybe<Response>
|
||||
Sender::createResponse()
|
||||
Sender::createResponse(const std::string &response_body)
|
||||
{
|
||||
auto mb_json_body = request.getResponseFromFog();
|
||||
if (!mb_json_body.ok()) return mb_json_body.passErr();
|
||||
Response response(*mb_json_body, request.getSize(), request.isBulk());
|
||||
Response response(response_body, request.getSize(), request.isBulk());
|
||||
auto load_status = response.load();
|
||||
if (!load_status.ok()) return load_status.passErr();
|
||||
return response;
|
||||
|
@ -14,6 +14,9 @@
|
||||
#include "intelligence_invalidation.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include "boost/uuid/uuid_io.hpp"
|
||||
#include "boost/uuid/uuid.hpp"
|
||||
|
||||
#include "i_intelligence_is_v2.h"
|
||||
|
||||
@ -24,7 +27,8 @@ Invalidation::Invalidation(const string &class_value)
|
||||
:
|
||||
source_id(genError<void>()),
|
||||
object_type(genError<void>()),
|
||||
listening_id(genError<void>())
|
||||
listening_id(genError<void>()),
|
||||
registration_id(genError<void>())
|
||||
{
|
||||
setClassifier(ClassifierType::CLASS, class_value);
|
||||
}
|
||||
@ -36,20 +40,6 @@ Invalidation::setClassifier(ClassifierType type, const string &val)
|
||||
return *this;
|
||||
}
|
||||
|
||||
Invalidation &
|
||||
Invalidation::setStringAttr(const string &attr, const string &val, bool is_main)
|
||||
{
|
||||
is_main ? string_main_attr[attr] = val : string_attr[attr] = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Invalidation &
|
||||
Invalidation::setStringSetAttr(const string &attr, const set<string> &val, bool is_main)
|
||||
{
|
||||
is_main ? set_string_main_attr[attr] = val : set_string_attr[attr] = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Invalidation &
|
||||
Invalidation::setSourceId(const string &id)
|
||||
{
|
||||
@ -71,38 +61,6 @@ Invalidation::setInvalidationType(InvalidationType type)
|
||||
return *this;
|
||||
}
|
||||
|
||||
Maybe<string, void>
|
||||
Invalidation::getStringMainAttr(const string &attr) const
|
||||
{
|
||||
auto val_ref = string_main_attr.find(attr);
|
||||
if (val_ref == string_main_attr.end()) return genError<void>();
|
||||
return val_ref->second;
|
||||
}
|
||||
|
||||
Maybe<set<string>, void>
|
||||
Invalidation::getStringSetMainAttr(const string &attr) const
|
||||
{
|
||||
auto val_ref = set_string_main_attr.find(attr);
|
||||
if (val_ref == set_string_main_attr.end()) return genError<void>();
|
||||
return val_ref->second;
|
||||
}
|
||||
|
||||
Maybe<string, void>
|
||||
Invalidation::getStringAttr(const string &attr) const
|
||||
{
|
||||
auto val_ref = string_attr.find(attr);
|
||||
if (val_ref == string_attr.end()) return genError<void>();
|
||||
return val_ref->second;
|
||||
}
|
||||
|
||||
Maybe<set<string>, void>
|
||||
Invalidation::getStringSetAttr(const string &attr) const
|
||||
{
|
||||
auto val_ref = set_string_attr.find(attr);
|
||||
if (val_ref == set_string_attr.end()) return genError<void>();
|
||||
return val_ref->second;
|
||||
}
|
||||
|
||||
bool
|
||||
Invalidation::report(I_Intelligence_IS_V2 *interface) const
|
||||
{
|
||||
@ -113,6 +71,7 @@ Invalidation::report(I_Intelligence_IS_V2 *interface) const
|
||||
Maybe<uint>
|
||||
Invalidation::startListening(I_Intelligence_IS_V2 *interface, const function<void(const Invalidation &)> &cb)
|
||||
{
|
||||
registration_id = to_string(boost::uuids::random_generator()());
|
||||
auto res = interface->registerInvalidation(*this, cb);
|
||||
if (res.ok()) listening_id = *res;
|
||||
return res;
|
||||
@ -176,53 +135,29 @@ Invalidation::genObject() const
|
||||
if (object_type.ok()) invalidation <<", \"objectType\": \"" << convertObjectType.at(*object_type) << '"';
|
||||
invalidation << ", \"invalidationType\": \"" << convertInvalidationType.at(invalidation_type) << '"';
|
||||
if (source_id.ok()) invalidation <<", \"sourceId\": \"" << *source_id << '"';
|
||||
if (registration_id.ok()) invalidation <<", \"invalidationRegistrationId\": \"" << *registration_id << '"';
|
||||
|
||||
if (!string_main_attr.empty() || !set_string_main_attr.empty()) {
|
||||
if (!main_attributes.empty()) {
|
||||
invalidation << ", \"mainAttributes\": [ ";
|
||||
bool first = true;
|
||||
for (auto &attr : string_main_attr) {
|
||||
for (auto &main_attr : main_attributes) {
|
||||
if (!first) invalidation << ", ";
|
||||
invalidation << "{ \"" << attr.first << "\": \"" << attr.second << "\" }";
|
||||
auto val = main_attr.genObject();
|
||||
if (!val.ok()) continue;
|
||||
invalidation << *val;
|
||||
first = false;
|
||||
}
|
||||
|
||||
for (auto &attr : set_string_main_attr) {
|
||||
if (!first) invalidation << ", ";
|
||||
auto val = makeSeparatedStr(attr.second, ", ");
|
||||
invalidation << "{ \"" << attr.first << "\": [ ";
|
||||
bool internal_first = true;
|
||||
for (auto &value : attr.second) {
|
||||
if (!internal_first) invalidation << ", ";
|
||||
invalidation << "\"" << value << "\"";
|
||||
internal_first = false;
|
||||
}
|
||||
invalidation << " ] }";
|
||||
first = false;
|
||||
}
|
||||
|
||||
invalidation << " ]";
|
||||
}
|
||||
|
||||
if (!string_attr.empty() || !set_string_attr.empty()) {
|
||||
if (!attributes.empty()) {
|
||||
invalidation << ", \"attributes\": [ ";
|
||||
bool first = true;
|
||||
for (auto &attr : string_attr) {
|
||||
for (auto &attr : attributes) {
|
||||
if (!first) invalidation << ", ";
|
||||
invalidation << "{ \"" << attr.first << "\": \"" << attr.second << "\" }";
|
||||
first = false;
|
||||
}
|
||||
|
||||
for (auto &attr : set_string_attr) {
|
||||
if (!first) invalidation << ", ";
|
||||
auto val = makeSeparatedStr(attr.second, ", ");
|
||||
invalidation << "{ \"" << attr.first << "\": [ ";
|
||||
bool internal_first = true;
|
||||
for (auto &value : attr.second) {
|
||||
if (!internal_first) invalidation << ", ";
|
||||
invalidation << "\"" << value << "\"";
|
||||
internal_first = false;
|
||||
}
|
||||
invalidation << " ] }";
|
||||
auto val = attr.genObject();
|
||||
if (!val.ok()) continue;
|
||||
invalidation << *val;
|
||||
first = false;
|
||||
}
|
||||
|
||||
@ -237,7 +172,7 @@ Invalidation::genObject() const
|
||||
bool
|
||||
Invalidation::isLegalInvalidation() const
|
||||
{
|
||||
if (!set_string_main_attr.empty() || !string_main_attr.empty()) {
|
||||
if (!main_attributes.empty() || !attributes.empty()) {
|
||||
if (classifiers[ClassifierType::FAMILY] == "") return false;
|
||||
}
|
||||
|
||||
@ -253,6 +188,18 @@ Invalidation::isLegalInvalidation() const
|
||||
template <>
|
||||
class EnumCount<ClassifierType> : public EnumCountSpecialization<ClassifierType, 6> {};
|
||||
|
||||
bool
|
||||
Invalidation::attr_matches(const vector<StrAttributes> ¤t, const vector<StrAttributes> &other) const
|
||||
{
|
||||
if (current.empty()) return true;
|
||||
for (auto &attr : current) {
|
||||
for(auto &other_attr : other) {
|
||||
if (attr.matches(other_attr)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Invalidation::matches(const Invalidation &other) const
|
||||
{
|
||||
@ -264,53 +211,104 @@ Invalidation::matches(const Invalidation &other) const
|
||||
if (!other.object_type.ok() || *object_type != *other.object_type) return false;
|
||||
}
|
||||
|
||||
if (invalidation_type != other.invalidation_type) return false;
|
||||
|
||||
if (source_id.ok()) {
|
||||
if (!other.source_id.ok() || *source_id != *other.source_id) return false;
|
||||
}
|
||||
|
||||
for (auto &key_value : string_main_attr) {
|
||||
if (!other.hasMainAttr(key_value.first, key_value.second)) return false;
|
||||
}
|
||||
if (!attr_matches(main_attributes, other.getMainAttributes())) return false;
|
||||
|
||||
|
||||
for (auto &key_values : set_string_main_attr) {
|
||||
for (auto &value : key_values.second) {
|
||||
if (!other.hasMainAttr(key_values.first, value)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &key_value : string_attr) {
|
||||
if (!other.hasAttr(key_value.first, key_value.second)) return false;
|
||||
}
|
||||
|
||||
|
||||
for (auto &key_values : set_string_attr) {
|
||||
for (auto &value : key_values.second) {
|
||||
if (!other.hasAttr(key_values.first, value)) return false;
|
||||
}
|
||||
}
|
||||
if(!attr_matches(attributes, other.getAttributes())) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Invalidation::hasMainAttr(const string &key, const string &value) const
|
||||
Invalidation &
|
||||
Invalidation::addAttr(const StrAttributes &attr)
|
||||
{
|
||||
auto string_elem = string_main_attr.find(key);
|
||||
if (string_elem != string_main_attr.end()) return string_elem->second == value;
|
||||
attributes.emplace_back(attr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto set_string_elem = set_string_main_attr.find(key);
|
||||
if (set_string_elem != set_string_main_attr.end()) {
|
||||
return set_string_elem->second.find(value) != set_string_elem->second.end();
|
||||
Invalidation &
|
||||
Invalidation::addMainAttr(const StrAttributes &attr)
|
||||
{
|
||||
main_attributes.emplace_back(attr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Maybe<string, void>
|
||||
Invalidation::getRegistrationID() const{
|
||||
return registration_id;
|
||||
}
|
||||
|
||||
StrAttributes &
|
||||
StrAttributes::addStringAttr(const std::string &attr, const std::string &val)
|
||||
{
|
||||
string_attr[attr] = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
StrAttributes &
|
||||
StrAttributes::addStringSetAttr(const std::string &attr, const std::set<std::string> &val)
|
||||
{
|
||||
set_string_attr[attr] = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Maybe<std::string, void>
|
||||
StrAttributes::getStringAttr(const std::string &attr) const
|
||||
{
|
||||
auto val_ref = string_attr.find(attr);
|
||||
if (val_ref == string_attr.end()) return genError<void>();
|
||||
return val_ref->second;
|
||||
}
|
||||
|
||||
Maybe<std::set<std::string>, void>
|
||||
StrAttributes::getStringSetAttr(const string &attr) const
|
||||
{
|
||||
auto val_ref = set_string_attr.find(attr);
|
||||
if (val_ref == set_string_attr.end()) return genError<void>();
|
||||
return val_ref->second;
|
||||
}
|
||||
|
||||
Maybe<std::string, void>
|
||||
StrAttributes::genObject() const
|
||||
{
|
||||
stringstream attributes_ss;
|
||||
if (string_attr.empty() && set_string_attr.empty()) return genError<void>();
|
||||
bool first = true;
|
||||
attributes_ss << "{ ";
|
||||
for (auto &attr : string_attr) {
|
||||
if (!first) attributes_ss << ", ";
|
||||
attributes_ss << "\"" << attr.first << "\": \"" << attr.second << "\"";
|
||||
first = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
for (auto &attr : set_string_attr) {
|
||||
if (!first) attributes_ss << ", ";
|
||||
auto val = makeSeparatedStr(attr.second, ", ");
|
||||
attributes_ss << "\"" << attr.first << "\": [ ";
|
||||
bool internal_first = true;
|
||||
for (auto &value : attr.second) {
|
||||
if (!internal_first) attributes_ss << ", ";
|
||||
attributes_ss << "\"" << value << "\"";
|
||||
internal_first = false;
|
||||
}
|
||||
attributes_ss << " ]";
|
||||
first = false;
|
||||
}
|
||||
attributes_ss << " }";
|
||||
return attributes_ss.str();
|
||||
}
|
||||
|
||||
bool
|
||||
Invalidation::hasAttr(const string &key, const string &value) const
|
||||
StrAttributes::isEmpty() const
|
||||
{
|
||||
return string_attr.empty() && set_string_attr.empty();
|
||||
}
|
||||
|
||||
bool
|
||||
StrAttributes::hasAttr(const string &key, const string &value) const
|
||||
{
|
||||
auto string_elem = string_attr.find(key);
|
||||
if (string_elem != string_attr.end()) return string_elem->second == value;
|
||||
@ -322,3 +320,54 @@ Invalidation::hasAttr(const string &key, const string &value) const
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
StrAttributes::matches(const StrAttributes &other) const
|
||||
{
|
||||
for (auto &key_value : string_attr) {
|
||||
if (!other.hasAttr(key_value.first, key_value.second)) return false;
|
||||
}
|
||||
|
||||
for (auto &key_values : set_string_attr) {
|
||||
for (auto &value : key_values.second) {
|
||||
if (!other.hasAttr(key_values.first, value)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
StrAttributes::serialize(cereal::JSONInputArchive &ar)
|
||||
{
|
||||
SerializableMultiMap<string, set<string>> attributes_map;
|
||||
attributes_map.load(ar);
|
||||
string_attr = attributes_map.getMap<string>();
|
||||
set_string_attr = attributes_map.getMap<set<string>>();
|
||||
}
|
||||
|
||||
void
|
||||
StrAttributes::performOutputingSchema(ostream &out, int level) {
|
||||
bool first = true;
|
||||
RestHelper::printIndent(out, level) << "{\n";
|
||||
for (auto &attr : string_attr) {
|
||||
if (!first) out << ",\n";
|
||||
RestHelper::printIndent(out, level + 1) << "\"" << attr.first << "\": \"" << attr.second << "\"";
|
||||
first = false;
|
||||
}
|
||||
|
||||
for (auto &attr : set_string_attr) {
|
||||
if (!first) out << ",\n";
|
||||
RestHelper::printIndent(out, level + 1) << "\"" << attr.first << "\": [\n";
|
||||
bool internal_first = true;
|
||||
for (auto &value : attr.second) {
|
||||
if (!internal_first) out << ",\n";
|
||||
RestHelper::printIndent(out, level + 2) << "\"" << value << "\"";
|
||||
internal_first = false;
|
||||
}
|
||||
out << "\n";
|
||||
RestHelper::printIndent(out, level + 1) << "]\n";
|
||||
first = false;
|
||||
}
|
||||
RestHelper::printIndent(out, level) << "}";
|
||||
}
|
||||
|
@ -438,6 +438,26 @@ private:
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
BioConnectionStatus
|
||||
tryToBioConnect(const string &full_address)
|
||||
{
|
||||
BIO_set_conn_hostname(bio.get(), full_address.c_str());
|
||||
BIO_set_nbio(bio.get(), 1);
|
||||
auto bio_connect = BIO_do_connect(bio.get());
|
||||
|
||||
if (bio_connect > 0) return BioConnectionStatus::SUCCESS;
|
||||
if (BIO_should_retry(bio.get())) return BioConnectionStatus::SHOULD_RETRY;
|
||||
|
||||
string bio_error = ERR_error_string(ERR_get_error(), nullptr);
|
||||
dbgWarning(D_CONNECTION)
|
||||
<< "Connection to: "
|
||||
<< full_address
|
||||
<< " failed and won't retry. Error: "
|
||||
<< bio_error;
|
||||
return BioConnectionStatus::SHOULD_NOT_RETRY;
|
||||
}
|
||||
|
||||
|
||||
Maybe<void>
|
||||
connectToHost()
|
||||
{
|
||||
@ -449,45 +469,43 @@ private:
|
||||
}
|
||||
|
||||
dbgFlow(D_CONNECTION) << "Connecting to " << full_address;
|
||||
BIO_set_conn_hostname(bio.get(), full_address.c_str());
|
||||
BIO_set_nbio(bio.get(), 1);
|
||||
|
||||
I_MainLoop *i_mainloop = Singleton::Consume<I_MainLoop>::by<Messaging>();
|
||||
I_TimeGet *i_time = Singleton::Consume<I_TimeGet>::by<Messaging>();
|
||||
|
||||
auto bio_connect = BIO_do_connect(bio.get());
|
||||
BioConnectionStatus bio_connect = tryToBioConnect(full_address);
|
||||
uint attempts_count = 0;
|
||||
auto conn_end_time = i_time->getMonotonicTime() + getConnectionTimeout();
|
||||
while (i_time->getMonotonicTime() < conn_end_time && bio_connect <= 0) {
|
||||
if (!BIO_should_retry(bio.get())) {
|
||||
auto curr_time = chrono::duration_cast<chrono::seconds>(i_time->getMonotonicTime());
|
||||
active = genError(curr_time + chrono::seconds(60));
|
||||
string bio_error = ERR_error_string(ERR_get_error(), nullptr);
|
||||
return genError(
|
||||
"Failed to connect to: " +
|
||||
full_address +
|
||||
", error: " +
|
||||
bio_error +
|
||||
". Connection suspended for 60 seconds");
|
||||
}
|
||||
attempts_count++;
|
||||
if (!isBioSocketReady()) {
|
||||
while (i_time->getMonotonicTime() < conn_end_time && bio_connect == BioConnectionStatus::SHOULD_RETRY) {
|
||||
if (isBioSocketReady()) {
|
||||
bio_connect = tryToBioConnect(full_address);
|
||||
} else {
|
||||
i_mainloop->yield((attempts_count % 10) == 0);
|
||||
continue;
|
||||
}
|
||||
bio_connect = BIO_do_connect(bio.get());
|
||||
}
|
||||
if (bio_connect > 0) {
|
||||
|
||||
if (bio_connect == BioConnectionStatus::SUCCESS) {
|
||||
if (isUnsecure() || isOverProxy()) return Maybe<void>();
|
||||
return performHandshakeAndVerifyCert(i_time, i_mainloop);
|
||||
}
|
||||
|
||||
if (bio_connect == BioConnectionStatus::SHOULD_NOT_RETRY) {
|
||||
auto curr_time = chrono::duration_cast<chrono::seconds>(i_time->getMonotonicTime());
|
||||
active = genError(curr_time + chrono::seconds(60));
|
||||
dbgWarning(D_CONNECTION)
|
||||
<< "Connection to: "
|
||||
<< full_address
|
||||
<< " failed and will be suspended for 60 seconds";
|
||||
return genError(full_address + ". There won't be a retry attempt.");
|
||||
}
|
||||
|
||||
auto curr_time = chrono::duration_cast<chrono::seconds>(i_time->getMonotonicTime());
|
||||
active = genError(curr_time + chrono::seconds(60));
|
||||
return genError(
|
||||
"Failed to establish new connection to: " +
|
||||
full_address +
|
||||
" after reaching timeout." +
|
||||
" Connection suspended for 60 seconds");
|
||||
dbgWarning(D_CONNECTION)
|
||||
<< "Connection attempts to: "
|
||||
<< full_address
|
||||
<< " have reached timeout and will be suspended for 60 seconds";
|
||||
return genError(full_address + ". Connection has reached timeout.");
|
||||
}
|
||||
|
||||
Maybe<uint, HTTPResponse>
|
||||
@ -592,7 +610,7 @@ private:
|
||||
auto send_size = sendData(request, data_left_to_send);
|
||||
if (!send_size.ok()) return send_size.passErr();
|
||||
data_left_to_send -= *send_size;
|
||||
i_mainloop->yield(*send_size == 0); // We want to force waiting if we failed to send the data
|
||||
i_mainloop->yield(*send_size == 0);
|
||||
}
|
||||
|
||||
auto receiving_end_time = i_time->getMonotonicTime() + getConnectionTimeout();
|
||||
|
@ -62,7 +62,7 @@ MessagingComp::getConnection(MessageCategory category, const MessageMetadata &me
|
||||
|
||||
auto maybe_conn = i_conn->establishConnection(metadata, category);
|
||||
if (!maybe_conn.ok()) {
|
||||
dbgWarning(D_MESSAGING) << "Failed to establish connection: " << maybe_conn.getErr();
|
||||
dbgWarning(D_MESSAGING) << maybe_conn.getErr();
|
||||
}
|
||||
return maybe_conn;
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ RestServer::Impl::init()
|
||||
|
||||
auto is_primary = Singleton::Consume<I_Environment>::by<RestServer>()->get<bool>("Is Rest primary routine");
|
||||
id = mainloop->addFileRoutine(
|
||||
I_MainLoop::RoutineType::RealTime,
|
||||
I_MainLoop::RoutineType::Offline,
|
||||
fd,
|
||||
[&] () { this->startNewConnection(); },
|
||||
"REST server listener",
|
||||
@ -174,7 +174,7 @@ RestServer::Impl::startNewConnection() const
|
||||
|
||||
RestConn conn(new_socket, mainloop, this);
|
||||
mainloop->addFileRoutine(
|
||||
I_MainLoop::RoutineType::RealTime,
|
||||
I_MainLoop::RoutineType::Offline,
|
||||
new_socket,
|
||||
[conn] () { conn.parseConn(); },
|
||||
"REST server connection handler"
|
||||
|
@ -1287,6 +1287,8 @@ extractServices(const vector<string> &args)
|
||||
services.push_back(Service::SDWAN);
|
||||
} else if (getServiceString(Service::LOGGER_SDWAN).find(maybe_service) == 0) {
|
||||
services.push_back(Service::LOGGER_SDWAN);
|
||||
} else if (getServiceString(Service::CPVIEW_METRIC_PROVIDER).find(maybe_service) == 0) {
|
||||
services.push_back(Service::CPVIEW_METRIC_PROVIDER);
|
||||
} else if (getServiceString(Service::IOT_WLP).find(maybe_service) == 0) {
|
||||
services.push_back(Service::IOT_WLP);
|
||||
} else if (getServiceString(Service::IDA).find(maybe_service) == 0) {
|
||||
|
@ -7,6 +7,8 @@ SMB_LOG_FILE_PATH="/storage"
|
||||
USR_LIB_PATH="/usr/lib"
|
||||
USR_SBIN_PATH="/usr/sbin"
|
||||
INIT_D_PATH="/etc/init.d"
|
||||
NANO_AGENT_SERVICE_NAME="nano_agent"
|
||||
NANO_AGENT_SERVICE_FILE="${NANO_AGENT_SERVICE_NAME}.service"
|
||||
CONF_PATH="conf"
|
||||
CERTS_PATH="certs"
|
||||
DATA_PATH="data"
|
||||
@ -19,6 +21,8 @@ ENV_DETAILS_FILE="${CONF_PATH}/environment-details.cfg"
|
||||
WATCHDOG_MAX_ROTATIONS=10
|
||||
WATCHDOG_MAX_FILE_SIZE=4096
|
||||
FORCE_CLEAN_FLAG='^(--force-clean|-f)$'
|
||||
VS_ID=""
|
||||
VS_LIB_SUB_FOLDER=
|
||||
|
||||
is_wlp_orchestration="false"
|
||||
ORCHESTRATION_EXE_SOURCE_PATH="./bin/orchestration_comp"
|
||||
@ -211,7 +215,6 @@ if [ -n "${CP_USR_SBIN_PATH}" ]; then
|
||||
export PATH=$PATH:$CP_USR_SBIN_PATH
|
||||
fi
|
||||
|
||||
|
||||
while true; do
|
||||
if [ "$1" = "--arm32_openwrt" ]; then
|
||||
var_arch="arm"
|
||||
@ -294,6 +297,14 @@ while true; do
|
||||
FILESYSTEM_PATH=$1
|
||||
fi
|
||||
echo "Filesystem paths: ${FILESYSTEM_PATH}"
|
||||
elif [ "$1" = "--vs_id" ]; then
|
||||
shift
|
||||
VS_ID=$1
|
||||
FILESYSTEM_PATH="/etc/cp/vs${VS_ID}"
|
||||
NANO_AGENT_SERVICE_NAME="nano_agent_${VS_ID}"
|
||||
NANO_AGENT_SERVICE_FILE="${NANO_AGENT_SERVICE_NAME}.service"
|
||||
VS_LIB_SUB_FOLDER="/vs${VS_ID}"
|
||||
LOG_FILE_PATH="${LOG_FILE_PATH}/vs${VS_ID}"
|
||||
elif [ "$1" = "--log_files_path" ]; then
|
||||
shift
|
||||
var=$1
|
||||
@ -324,6 +335,23 @@ while true; do
|
||||
shift
|
||||
done
|
||||
|
||||
# VS ID argument is available only on install, for other actions, extract it from the package location
|
||||
if [ -z "$VS_ID" ]; then
|
||||
parent_pid=$PPID
|
||||
parent_cmdline=$(ps -o cmd= -p "$parent_pid")
|
||||
parent_dir=$(dirname "$parent_cmdline")
|
||||
packages_folder=$(dirname "$parent_dir")
|
||||
vs_folder=$(dirname "$packages_folder")
|
||||
VS_ID=`echo ${vs_folder} | grep -oE '/etc/cp/vs[0-9]+$' | grep -oE '[0-9]+$'`
|
||||
if [ -n "$VS_ID" ]; then
|
||||
FILESYSTEM_PATH="/etc/cp/vs${VS_ID}"
|
||||
NANO_AGENT_SERVICE_NAME="nano_agent_${VS_ID}"
|
||||
NANO_AGENT_SERVICE_FILE="${NANO_AGENT_SERVICE_NAME}.service"
|
||||
VS_LIB_SUB_FOLDER="/vs${VS_ID}"
|
||||
LOG_FILE_PATH="${LOG_FILE_PATH}/vs${VS_ID}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$RUN_MODE" = "install" ] && [ $var_offline_mode = false ]; then
|
||||
if [ -n "$OTP_TOKEN" ] && [ -z "$var_token" ] && [ "$var_no_otp" = "false" ]; then
|
||||
var_token=$OTP_TOKEN
|
||||
@ -464,23 +492,30 @@ update_cloudguard_appsec_manifest()
|
||||
|
||||
install_watchdog_gaia()
|
||||
{
|
||||
watchdog_pm_name="cp-nano-watchdog"
|
||||
if [ -n "$VS_ID" ]; then
|
||||
watchdog_pm_name="cp-nano-watchdog-vs${VS_ID}"
|
||||
cp_exec "ln -s ${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog ${FILESYSTEM_PATH}/${WATCHDOG_PATH}/${watchdog_pm_name}"
|
||||
fi
|
||||
|
||||
# verify that DB is clean from cp-nano-watchdog
|
||||
tellpm cp-nano-watchdog
|
||||
dbset process:cp-nano-watchdog
|
||||
dbset process:cp-nano-watchdog:path
|
||||
dbset process:cp-nano-watchdog:arg:1
|
||||
dbset process:cp-nano-watchdog:runlevel
|
||||
tellpm ${watchdog_pm_name}
|
||||
dbset process:${watchdog_pm_name}
|
||||
dbset process:${watchdog_pm_name}:path
|
||||
dbset process:${watchdog_pm_name}:arg:1
|
||||
dbset process:${watchdog_pm_name}:runlevel
|
||||
# Add cp-nano-watchdog to DB
|
||||
dbset process:cp-nano-watchdog t
|
||||
dbset process:cp-nano-watchdog:path ${FILESYSTEM_PATH}/${WATCHDOG_PATH}
|
||||
dbset process:cp-nano-watchdog:arg:1 --gaia
|
||||
dbset process:cp-nano-watchdog:runlevel 1
|
||||
dbset process:${watchdog_pm_name} t
|
||||
dbset process:${watchdog_pm_name}:path ${FILESYSTEM_PATH}/${WATCHDOG_PATH}
|
||||
dbset process:${watchdog_pm_name}:arg:1 --gaia
|
||||
dbset process:${watchdog_pm_name}:runlevel 1
|
||||
dbset :save
|
||||
tellpm cp-nano-watchdog t
|
||||
tellpm ${watchdog_pm_name} t
|
||||
}
|
||||
|
||||
install_watchdog()
|
||||
{
|
||||
is_upgrade=$1
|
||||
# Check if watchdog is updated/new
|
||||
old_cp_nano_watchdog_md5=""
|
||||
new_cp_nano_watchdog_md5=$(md5sum watchdog/watchdog | awk '{print$1}')
|
||||
@ -489,8 +524,8 @@ install_watchdog()
|
||||
fi
|
||||
if [ "$old_cp_nano_watchdog_md5" = "$new_cp_nano_watchdog_md5" ]; then
|
||||
# Watchdog did not changed
|
||||
cp_print "There is no update in watchdog. Everything is up to date. Reregistering services to be on the sae side."
|
||||
cp_exec "${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --register ${FILESYSTEM_PATH}/${SERVICE_PATH}/cp-nano-orchestration $var_arch_flag"
|
||||
cp_print "There is no update in watchdog. Everything is up to date. Reregistering services to be on the same side."
|
||||
cp_exec "${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --register $is_upgrade ${FILESYSTEM_PATH}/${SERVICE_PATH}/cp-nano-orchestration $var_arch_flag"
|
||||
if [ "$IS_K8S_ENV" = "true" ]; then
|
||||
cp_exec "${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --register ${FILESYSTEM_PATH}/${SERVICE_PATH}/k8s-check-update-listener.sh"
|
||||
fi
|
||||
@ -502,10 +537,11 @@ install_watchdog()
|
||||
cp_exec "mkdir -p ${FILESYSTEM_PATH}/${WATCHDOG_PATH}"
|
||||
cp_copy watchdog/watchdog ${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog
|
||||
cp_copy watchdog/wait-for-networking-inspection-modules.sh ${FILESYSTEM_PATH}/${WATCHDOG_PATH}/wait-for-networking-inspection-modules.sh
|
||||
cp_exec "chmod 700 ${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog"
|
||||
cp_exec "chmod 700 ${FILESYSTEM_PATH}/${WATCHDOG_PATH}/wait-for-networking-inspection-modules.sh"
|
||||
cp_exec "chmod 700 ${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog"
|
||||
cp_exec "chmod 700 ${FILESYSTEM_PATH}/${WATCHDOG_PATH}/wait-for-networking-inspection-modules.sh"
|
||||
cp_exec "touch ${FILESYSTEM_PATH}/${WATCHDOG_PATH}/wd.services"
|
||||
cp_exec "${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --register ${FILESYSTEM_PATH}/${SERVICE_PATH}/cp-nano-orchestration $var_arch_flag"
|
||||
|
||||
cp_exec "${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --register $is_upgrade ${FILESYSTEM_PATH}/${SERVICE_PATH}/cp-nano-orchestration $var_arch_flag"
|
||||
if [ "$IS_K8S_ENV" = "true" ]; then
|
||||
cp_exec "${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --register ${FILESYSTEM_PATH}/${SERVICE_PATH}/k8s-check-update-listener.sh"
|
||||
fi
|
||||
@ -533,11 +569,15 @@ install_watchdog()
|
||||
cp_exec "ln -s ${CPDIR}/bin/cpopenssl ${CPDIR}/bin/openssl"
|
||||
elif [ $var_startup_service = "systemd" ]; then
|
||||
cp_print "Install for systemd"
|
||||
cp_copy service/x86/ubuntu16/nano_agent.service /etc/systemd/system/nano_agent.service
|
||||
echo "ExecStart=${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog" >> /etc/systemd/system/nano_agent.service
|
||||
echo "ExecStartPost=${FILESYSTEM_PATH}/${WATCHDOG_PATH}/wait-for-networking-inspection-modules.sh" >> /etc/systemd/system/nano_agent.service
|
||||
echo "Environment=\"FILESYSTEM_PATH=${FILESYSTEM_PATH}\"" >> /etc/systemd/system/nano_agent.service
|
||||
|
||||
cp_copy service/x86/ubuntu16/nano_agent.service /etc/systemd/system/${NANO_AGENT_SERVICE_FILE}
|
||||
if [ -z "$VS_ID" ]; then
|
||||
echo "ExecStart=${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog" >> /etc/systemd/system/${NANO_AGENT_SERVICE_FILE}
|
||||
echo "ExecStartPost=${FILESYSTEM_PATH}/${WATCHDOG_PATH}/wait-for-networking-inspection-modules.sh" >> /etc/systemd/system/${NANO_AGENT_SERVICE_FILE}
|
||||
else
|
||||
echo "ExecStart=ip netns exec CTX0000${VS_ID} ${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog" >> /etc/systemd/system/${NANO_AGENT_SERVICE_FILE}
|
||||
fi
|
||||
echo "Environment=\"FILESYSTEM_PATH=${FILESYSTEM_PATH}\"" >> /etc/systemd/system/${NANO_AGENT_SERVICE_FILE}
|
||||
|
||||
cp_exec "systemctl daemon-reload"
|
||||
cp_exec "systemctl enable nano_agent"
|
||||
else
|
||||
@ -562,7 +602,7 @@ install_watchdog()
|
||||
elif [ $var_arch = "gaia" ]; then
|
||||
install_watchdog_gaia
|
||||
else
|
||||
cp_exec "service nano_agent start"
|
||||
cp_exec "service $NANO_AGENT_SERVICE_NAME start"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@ -601,7 +641,7 @@ install_cp_nano_ctl()
|
||||
cp_exec "rm -rf $USR_SBIN_PATH/${CP_NANO_CTL_DEPRECATED}"
|
||||
fi
|
||||
# Removing old CP-CTL
|
||||
if [ -f ${FILESYSTEM_PATH}/${CONF_PATH}/CP_NANO_AGENT_CTL ]; then
|
||||
if [ -f ${FILESYSTEM_PATH}/${CONF_PATH}/$CP_NANO_AGENT_CTL ]; then
|
||||
cp_exec "rm -rf ${FILESYSTEM_PATH}/${CONF_PATH}/$CP_NANO_AGENT_CTL"
|
||||
fi
|
||||
|
||||
@ -612,6 +652,9 @@ install_cp_nano_ctl()
|
||||
cp_exec "cp -f $CP_NANO_CLI ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/$CP_NANO_AGENT_CTL"
|
||||
cp_exec "chmod 700 ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/$CP_NANO_AGENT_CTL"
|
||||
|
||||
if [ -n "$VS_ID" ]; then
|
||||
CP_NANO_CTL="${CP_NANO_CTL}-vs${VS_ID}"
|
||||
fi
|
||||
cp_exec "ln -s ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/$CP_NANO_AGENT_CTL $USR_SBIN_PATH/${CP_NANO_CTL}"
|
||||
cp_exec "ln -s ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/${OPEN_APPSEC_CTL}.sh $USR_SBIN_PATH/${OPEN_APPSEC_CTL}"
|
||||
|
||||
@ -804,16 +847,17 @@ uninstall_messaging_proxy_if_needed()
|
||||
install_orchestration()
|
||||
{
|
||||
INSTALLATION_TIME=$(date)
|
||||
|
||||
if [ "$is_smb" != "1" ]; then
|
||||
cp_exec "mkdir -p ${USR_LIB_PATH}/cpnano"
|
||||
cp_exec "mkdir -p ${USR_LIB_PATH}/cpnano${VS_LIB_SUB_FOLDER}"
|
||||
else
|
||||
cp_exec "mkdir -p /storage/nano_agent${USR_LIB_PATH}/cpnano"
|
||||
cp_exec "ln -sf /storage/nano_agent${USR_LIB_PATH}/cpnano ${USR_LIB_PATH}/cpnano"
|
||||
cp_exec "mkdir -p /storage/nano_agent/${FILESYSTEM_PATH}"
|
||||
cp_exec "ln -sf /storage/nano_agent/${FILESYSTEM_PATH} ${FILESYSTEM_PATH}"
|
||||
fi
|
||||
${INSTALL_COMMAND} lib/*.so* ${USR_LIB_PATH}/cpnano/
|
||||
${INSTALL_COMMAND} lib/boost/*.so* ${USR_LIB_PATH}/cpnano/
|
||||
${INSTALL_COMMAND} lib/*.so* ${USR_LIB_PATH}/cpnano${VS_LIB_SUB_FOLDER}/
|
||||
${INSTALL_COMMAND} lib/boost/*.so* ${USR_LIB_PATH}/cpnano${VS_LIB_SUB_FOLDER}/
|
||||
|
||||
if [ $var_compact_mode = true ]; then
|
||||
[ -f /etc/environment ] && . "/etc/environment"
|
||||
@ -882,16 +926,15 @@ install_orchestration()
|
||||
|
||||
upgrade_conf_if_needed
|
||||
|
||||
install_watchdog
|
||||
cp_exec "${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --un-register ${FILESYSTEM_PATH}/${SERVICE_PATH}/cp-nano-orchestration $var_arch_flag"
|
||||
if [ "$IS_K8S_ENV" = "true" ]; then
|
||||
cp_exec "${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --un-register ${FILESYSTEM_PATH}/${SERVICE_PATH}/k8s-check-update-listener.sh"
|
||||
fi
|
||||
|
||||
cp_print "Upgrade to latest"
|
||||
|
||||
uninstall_messaging_proxy_if_needed
|
||||
|
||||
${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --un-register ${FILESYSTEM_PATH}/${SERVICE_PATH}/cp-nano-orchestration "$var_arch_flag" > /dev/null 2>&1
|
||||
if [ "$IS_K8S_ENV" = "true" ]; then
|
||||
${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --un-register ${FILESYSTEM_PATH}/${SERVICE_PATH}/k8s-check-update-listener.sh
|
||||
fi
|
||||
|
||||
if [ ! -f ${FILESYSTEM_PATH}/${DEFAULT_SETTINGS_PATH} ]; then
|
||||
echo "{\"agentSettings\": []}" > ${FILESYSTEM_PATH}/${DEFAULT_SETTINGS_PATH}
|
||||
fi
|
||||
@ -900,21 +943,18 @@ install_orchestration()
|
||||
copy_k8s_executable
|
||||
copy_nginx_metadata_script
|
||||
|
||||
${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --register ${FILESYSTEM_PATH}/${SERVICE_PATH}/cp-nano-orchestration $var_arch_flag
|
||||
if [ "$IS_K8S_ENV" = "true" ]; then
|
||||
${FILESYSTEM_PATH}/${WATCHDOG_PATH}/cp-nano-watchdog --register ${FILESYSTEM_PATH}/${SERVICE_PATH}/k8s-check-update-listener.sh
|
||||
fi
|
||||
install_watchdog "--upgrade"
|
||||
|
||||
cp_print "Upgrade completed successfully" ${FORCE_STDOUT}
|
||||
|
||||
if [ -f /etc/systemd/system/nano_agent.service ]; then
|
||||
cat "/etc/systemd/system/nano_agent.service" | grep -q "EnvironmentFile=/etc/environment"
|
||||
if [ -f /etc/systemd/system/${NANO_AGENT_SERVICE_FILE} ]; then
|
||||
cat "/etc/systemd/system/${NANO_AGENT_SERVICE_FILE}" | grep -q "EnvironmentFile=/etc/environment"
|
||||
result=$?
|
||||
|
||||
if [ $var_container_mode = false ] && [ $result -eq 0 ]; then
|
||||
sed -i "$ d" /etc/systemd/system/nano_agent.service
|
||||
echo "EnvironmentFile=/etc/environment" >> /etc/systemd/system/nano_agent.service
|
||||
echo >> /etc/systemd/system/nano_agent.service
|
||||
sed -i "$ d" /etc/systemd/system/${NANO_AGENT_SERVICE_FILE}
|
||||
echo "EnvironmentFile=/etc/environment" >> /etc/systemd/system/${NANO_AGENT_SERVICE_FILE}
|
||||
echo >> /etc/systemd/system/${NANO_AGENT_SERVICE_FILE}
|
||||
cp_exec "systemctl daemon-reload"
|
||||
cp_exec "systemctl restart nano_agent"
|
||||
fi
|
||||
@ -953,6 +993,9 @@ install_orchestration()
|
||||
if [ -n "${FILESYSTEM_PATH}" ]; then
|
||||
echo "CP_ENV_FILESYSTEM=${FILESYSTEM_PATH}" >> ${FILESYSTEM_PATH}/${ENV_DETAILS_FILE}
|
||||
fi
|
||||
if [ -n "${VS_ID}" ]; then
|
||||
echo "CP_VS_ID=${VS_ID}" >> ${FILESYSTEM_PATH}/${ENV_DETAILS_FILE}
|
||||
fi
|
||||
if [ -n "${LOG_FILE_PATH}" ]; then
|
||||
echo "CP_ENV_LOG_FILE=${LOG_FILE_PATH}" >> ${FILESYSTEM_PATH}/${ENV_DETAILS_FILE}
|
||||
fi
|
||||
@ -1095,19 +1138,19 @@ run_pre_install_test()
|
||||
run_post_install_test()
|
||||
{
|
||||
if [ $var_is_alpine = false ]; then
|
||||
if [ ! -f ${USR_LIB_PATH}/cpnano/libboost_chrono.so* ]; then
|
||||
if [ ! -f ${USR_LIB_PATH}/cpnano${VS_LIB_SUB_FOLDER}/libboost_chrono.so* ]; then
|
||||
cp_print "Error, libboost_chrono .so file is missing" ${FORCE_STDOUT}
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f ${USR_LIB_PATH}/cpnano/libboost_context.so* ]; then
|
||||
if [ ! -f ${USR_LIB_PATH}/cpnano${VS_LIB_SUB_FOLDER}/libboost_context.so* ]; then
|
||||
cp_print "Error, libboost_context .so file is missing" ${FORCE_STDOUT}
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f ${USR_LIB_PATH}/cpnano/libboost_system.so* ]; then
|
||||
if [ ! -f ${USR_LIB_PATH}/cpnano${VS_LIB_SUB_FOLDER}/libboost_system.so* ]; then
|
||||
cp_print "Error, libboost_system .so file is missing" ${FORCE_STDOUT}
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f ${USR_LIB_PATH}/cpnano/libboost_thread.so* ]; then
|
||||
if [ ! -f ${USR_LIB_PATH}/cpnano${VS_LIB_SUB_FOLDER}/libboost_thread.so* ]; then
|
||||
cp_print "Error, libboost_thread .so file is missing" ${FORCE_STDOUT}
|
||||
exit 1
|
||||
fi
|
||||
|
@ -1,17 +1,36 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ -z ${FILESYSTEM_PATH} ] && FILESYSTEM_PATH="/etc/cp"
|
||||
LOG_FILE_PATH="/var/log"
|
||||
SCRIPT_FOLDER=$(dirname "$0")
|
||||
PARENT_FOLDER=$(dirname "$SCRIPT_FOLDER")
|
||||
FILESYSTEM_PATH=$PARENT_FOLDER
|
||||
VS_ID_PATTERN="vs[0-9]\+$"
|
||||
VS_ID=
|
||||
TMP_FOLDER="/tmp"
|
||||
USR_LIB_PATH="/usr/lib"
|
||||
NGEN_LIB_PATH=${USR_LIB_PATH}/cpnano/
|
||||
if echo "$PARENT_FOLDER" | grep -q "$VS_ID_PATTERN"; then
|
||||
VS_ID="${PARENT_FOLDER##*vs}"
|
||||
TMP_FOLDER="/tmp/${VS_ID}"
|
||||
mkdir -p ${TMP_FOLDER}
|
||||
NGEN_LIB_PATH=${USR_LIB_PATH}/cpnano/vs${VS_ID}/
|
||||
if [ -f "/etc/bashrc" ]; then
|
||||
. /etc/bashrc
|
||||
vsenv ${VS_ID}
|
||||
fi
|
||||
fi
|
||||
LOG_FILE_PATH="/var/log"
|
||||
INIT_D_PATH="/etc/init.d"
|
||||
WATCHDOG_PROCESS_RESTART_COUNTER="/etc/cp/watchdog/watchdog_process_restart"
|
||||
WATCHDOG_PROCESS_RESTART_COUNTER="${FILESYSTEM_PATH}/watchdog/watchdog_process_restart"
|
||||
LOG_FILE=nano_agent/cp-nano-watchdog.dbg
|
||||
AGENT_RUN_STATUS_FILE=/tmp/agent-status.txt
|
||||
AGENT_RUN_STATUS_FILE=${TMP_FOLDER}/agent-status.txt
|
||||
SRVS_FILE=watchdog/wd.services
|
||||
STARTUP_SRVS_FILE=watchdog/wd.services.startup
|
||||
TMP_SRVS_FILE=watchdog/wd.temp
|
||||
VOL_SRVS_FILE=watchdog/wd.volatile_services
|
||||
SRVS_CONTAINER_FILE=watchdog/wd.container_services_startup
|
||||
SRVS_TO_RESTART_FILE=watchdog/wd.services.restart
|
||||
SRVS_TO_STOP_FILE=watchdog/wd.services.stop
|
||||
TMP_SRVS_TO_STOP_FILE=watchdog/wd.stop.temp
|
||||
TMP_VOL_SRVS_FILE_PRE_STOP=watchdog/wd.volatile_services.stop
|
||||
TMP_VOL_SRVS_FILE_PRE_DEL=watchdog/wd.volatile_services.del
|
||||
SRVS_HALTED=watchdog/wd.services.halt
|
||||
@ -24,7 +43,10 @@ env_details_file=conf/environment-details.cfg
|
||||
DEFAULT_MAX_FILE_SIZE=4096
|
||||
#default amount of archived log files to rotate
|
||||
DEFAULT_MAX_ROTATION=10
|
||||
VS_EVAL_PREFIX=
|
||||
|
||||
var_service_startup=
|
||||
var_upgarde=false
|
||||
|
||||
get_basename()
|
||||
{
|
||||
@ -50,8 +72,18 @@ load_paths()
|
||||
if [ -n "${CP_ENV_LOG_FILE}" ]; then
|
||||
LOG_FILE_PATH=$CP_ENV_LOG_FILE
|
||||
fi
|
||||
if [ -n "${CP_VS_ID}" ]; then
|
||||
VS_ID=${CP_VS_ID}
|
||||
VS_EVAL_PREFIX="ip netns exec CTX0000${VS_ID} env"
|
||||
NGEN_LIB_PATH=${USR_LIB_PATH}/cpnano/vs${VS_ID}/
|
||||
fi
|
||||
if [ -n "${CP_USR_LIB_PATH}" ]; then
|
||||
USR_LIB_PATH=$CP_USR_LIB_PATH
|
||||
if [ -z "${VS_ID}" ]; then
|
||||
NGEN_LIB_PATH=${USR_LIB_PATH}/cpnano/
|
||||
else
|
||||
NGEN_LIB_PATH=${USR_LIB_PATH}/cpnano/vs${VS_ID}/
|
||||
fi
|
||||
fi
|
||||
if [ -n "${CP_INIT_D_PATH}" ]; then
|
||||
INIT_D_PATH=$CP_INIT_D_PATH
|
||||
@ -63,12 +95,11 @@ load_paths()
|
||||
if [ -z "${MAX_ROTATION}" ]; then
|
||||
MAX_ROTATION=$DEFAULT_MAX_ROTATION
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
load_paths
|
||||
|
||||
NGEN_LIB_PATH=${USR_LIB_PATH}/cpnano/
|
||||
|
||||
pidof_cmd="pidof -x"
|
||||
if command -v pidof > /dev/null 2>&1; then
|
||||
PIDOF_CMD_EXISTS=1
|
||||
@ -102,7 +133,6 @@ alpine_pid()
|
||||
ps -ef | grep $1 | grep -v grep | awk '{printf $1 " "}'
|
||||
}
|
||||
|
||||
|
||||
ls -l /etc/ | grep release > /dev/null 2>&1
|
||||
retval=$?
|
||||
if [ $retval -eq 0 ]; then
|
||||
@ -173,9 +203,11 @@ sigterm()
|
||||
stop_instance $service $instance_id $family
|
||||
done
|
||||
rm ${FILESYSTEM_PATH}/${TMP_VOL_SRVS_FILE_PRE_STOP}
|
||||
# wait for kill_process_by_pid that is run async by stop_instance
|
||||
wait
|
||||
fi
|
||||
|
||||
echo "down" >>$AGENT_RUN_STATUS_FILE
|
||||
echo "down" > $AGENT_RUN_STATUS_FILE
|
||||
|
||||
log "sigterm" "cp-nano-agent watchdog service was successfully stopped "
|
||||
exit 0
|
||||
@ -189,6 +221,111 @@ stop()
|
||||
trap 'sigterm' TERM
|
||||
trap 'sigterm' INT
|
||||
|
||||
run_service()
|
||||
{
|
||||
service=$1
|
||||
execution_flags=
|
||||
srv_debug_file=
|
||||
srv_err_file=
|
||||
gaia_ld_path=$2
|
||||
run_in_vs=
|
||||
|
||||
log "run_service" "Running the service: $service"
|
||||
|
||||
if [ -f ${service}.cfg ]; then
|
||||
. "${service}.cfg"
|
||||
fi
|
||||
|
||||
if [ -z ${srv_debug_file} ]; then
|
||||
base_name=$(get_basename $service)
|
||||
srv_debug_file=${LOG_FILE_PATH}/nano_agent/${base_name}.dbg
|
||||
fi
|
||||
|
||||
if [ -z ${srv_err_file} ]; then
|
||||
base_name=$(get_basename $service)
|
||||
srv_err_file=${LOG_FILE_PATH}/nano_agent/${base_name}.err
|
||||
fi
|
||||
|
||||
if ! [ -z ${gaia_ld_path} ]; then
|
||||
if [ -n "$VS_ID" ]; then
|
||||
NGEN_LIB_PATH="${USR_LIB_PATH}/cpnano/vs${VS_ID}/:${gaia_ld_path}"
|
||||
else
|
||||
NGEN_LIB_PATH="${USR_LIB_PATH}/cpnano/:${gaia_ld_path}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$VS_ID" ]; then
|
||||
run_in_vs="ip netns exec CTX0000${VS_ID}"
|
||||
fi
|
||||
|
||||
if [ "${service}" = "${FILESYSTEM_PATH}/agentCache/cp-nano-agent-cache" ] || [ "${service}" = "${FILESYSTEM_PATH}/agentIntelligence/redis/redis-server" ] || [ "${service}" = "${FILESYSTEM_PATH}/crowdsecAux/cp-nano-crowdsec-aux" ]; then
|
||||
LD_LIBRARY_PATH=${NGEN_LIB_PATH} ${run_in_vs} ${service} ${execution_flags} 2>${srv_err_file} 1>/dev/null &
|
||||
else
|
||||
LD_LIBRARY_PATH=${NGEN_LIB_PATH} ${run_in_vs} ${service} ${execution_flags} --filesystem_path=${FILESYSTEM_PATH} --log_files_path=${LOG_FILE_PATH} --service_startup=${var_service_startup} 2>${srv_err_file} 1>/dev/null &
|
||||
fi
|
||||
}
|
||||
|
||||
run_volatile_service()
|
||||
{
|
||||
service_line=$1
|
||||
service=$(echo $service_line | cut -f1 -d ';')
|
||||
family=$(echo $service_line | cut -f2 -d ';')
|
||||
instance_id=$(echo $service_line | cut -f3 -d ';')
|
||||
already_running="0"
|
||||
execution_flags=
|
||||
srv_debug_file=
|
||||
srv_err_file=
|
||||
gaia_ld_path=$2
|
||||
|
||||
log "run_volatile_service" "Running the service: ${service} ($family : $instance_id)"
|
||||
|
||||
if [ -f ${service}.cfg ]; then
|
||||
. "${service}.cfg"
|
||||
fi
|
||||
|
||||
if [ -z $family ]; then
|
||||
debug_file_suffix=${instance_id}
|
||||
else
|
||||
debug_file_suffix=${family}_${instance_id}
|
||||
fi
|
||||
|
||||
if [ -z ${srv_debug_file} ]; then
|
||||
base_name=$(get_basename $service)
|
||||
srv_debug_file=${LOG_FILE_PATH}/nano_agent/$base_name.dbg${debug_file_suffix}
|
||||
fi
|
||||
|
||||
if [ -z ${srv_err_file} ]; then
|
||||
base_name=$(get_basename $service)
|
||||
srv_err_file=${LOG_FILE_PATH}/nano_agent/$base_name.err${debug_file_suffix}
|
||||
fi
|
||||
|
||||
if ! [ -z ${gaia_ld_path} ]; then
|
||||
if [ -n "$VS_ID" ]; then
|
||||
NGEN_LIB_PATH="${USR_LIB_PATH}/cpnano/vs${VS_ID}/:${gaia_ld_path}"
|
||||
else
|
||||
NGEN_LIB_PATH="${USR_LIB_PATH}/cpnano/:${gaia_ld_path}"
|
||||
fi
|
||||
if [ "$is_smb" = "1" -a "$SUB_HW_VER" = "THX2" ]; then
|
||||
NGEN_LIB_PATH="/lib64:/pfrm2.0/lib64:${NGEN_LIB_PATH}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$VS_ID" ]; then
|
||||
run_in_vs="ip netns exec CTX0000${VS_ID}"
|
||||
fi
|
||||
|
||||
family_arg=""
|
||||
if [ -n "${family}" ]; then
|
||||
family_arg="--family=${family}"
|
||||
fi
|
||||
|
||||
base_name=$(get_basename $service)
|
||||
srv_err_file=${LOG_FILE_PATH}/nano_agent/$base_name.err${debug_file_suffix}
|
||||
|
||||
echo -en "["$(date)"]" >> ${srv_debug_file}
|
||||
LD_LIBRARY_PATH=${NGEN_LIB_PATH} ${run_in_vs} ${service} ${execution_flags} --filesystem_path=${FILESYSTEM_PATH} --log_files_path=${LOG_FILE_PATH} --service_startup=${var_service_startup} ${family_arg} --id=${instance_id} 2>${srv_err_file} &
|
||||
}
|
||||
|
||||
register()
|
||||
{
|
||||
log "register" "enter"
|
||||
@ -198,6 +335,7 @@ register()
|
||||
family_name=$3
|
||||
|
||||
if [ -z $service_name ]; then
|
||||
log "register" "Error! no service provided for registration"
|
||||
echo "Error! no service provided for registration"
|
||||
exit 1
|
||||
fi
|
||||
@ -210,15 +348,30 @@ register()
|
||||
if [ -z $family_size ]; then
|
||||
#handle single instance services
|
||||
if ! [ -z "$(cat ${FILESYSTEM_PATH}/${SRVS_FILE} | grep ^${service_name}$)" ]; then
|
||||
log "register" "Warning! service '$service_name' is already registered"
|
||||
echo "Warning! service '$service_name' is already registered"
|
||||
exit 0
|
||||
fi
|
||||
echo "$service_name" >>${FILESYSTEM_PATH}/${SRVS_FILE}
|
||||
|
||||
if echo "$service_name" | grep -q "orchestration"; then
|
||||
temp_file=${FILESYSTEM_PATH}/${SRVS_FILE}.tmp
|
||||
echo "$service_name" | cat - ${FILESYSTEM_PATH}/${SRVS_FILE} > $temp_file
|
||||
mv $temp_file ${FILESYSTEM_PATH}/${SRVS_FILE}
|
||||
else
|
||||
echo "$service_name" >>${FILESYSTEM_PATH}/${SRVS_FILE}
|
||||
fi
|
||||
|
||||
if [ $var_upgarde = false ]; then
|
||||
log "register" "The service $service_name is running for the first time."
|
||||
echo "$service_name" >>${FILESYSTEM_PATH}/${STARTUP_SRVS_FILE}
|
||||
fi
|
||||
|
||||
else
|
||||
touch ${FILESYSTEM_PATH}/${VOL_SRVS_FILE}
|
||||
# handle multiple instances services
|
||||
family_prev_size=$(cat ${FILESYSTEM_PATH}/${VOL_SRVS_FILE} | grep "^$service_name;${family_name};" | wc -l)
|
||||
if [ $family_size -eq $family_prev_size ]; then
|
||||
log "register" "Service '$service_name' already registered with $family_size instances for family '${family_name}'"
|
||||
echo "Service '$service_name' already registered with $family_size instances for family '${family_name}'"
|
||||
exit 0
|
||||
fi
|
||||
@ -228,9 +381,15 @@ register()
|
||||
stop_instance $service_name ${i} ${family_name}
|
||||
done
|
||||
fi
|
||||
# wait for kill_process_by_pid that is run async by stop_instance
|
||||
wait
|
||||
grep -v -e "^${service_name};${family_name};" ${FILESYSTEM_PATH}/${TMP_VOL_SRVS_FILE_PRE_STOP} >${FILESYSTEM_PATH}/${TMP_VOL_SRVS_FILE_PRE_DEL}
|
||||
for i in $(seq 1 ${family_size}); do
|
||||
echo "$service_name;$family_name;$i" >>${FILESYSTEM_PATH}/${TMP_VOL_SRVS_FILE_PRE_DEL}
|
||||
if [ $var_upgarde = false ]; then
|
||||
log "register" "The service $service_name is running for the first time."
|
||||
echo "$service_name" >>${FILESYSTEM_PATH}/${STARTUP_SRVS_FILE}
|
||||
fi
|
||||
done
|
||||
mv ${FILESYSTEM_PATH}/${TMP_VOL_SRVS_FILE_PRE_DEL} ${FILESYSTEM_PATH}/${VOL_SRVS_FILE}
|
||||
rm ${FILESYSTEM_PATH}/${TMP_VOL_SRVS_FILE_PRE_STOP}
|
||||
@ -265,7 +424,7 @@ stop_instance()
|
||||
cmd_pid=$(ps -eo pid,cmd,args | grep -- "${family_arg}" | grep -- "--id=$instance_id" | awk -v srv=${1} '{if($2 ~ srv || $3 ~ srv) print $1}')
|
||||
fi
|
||||
if ! [ "${cmd_pid:-null}" = null ]; then
|
||||
log "stop_instance" "stopping $service_name (pid=$cmd_pid)"
|
||||
log "stop_instance" "Stopping registered service '$service_name', family $family_name, instance $instance_id with pid=$cmd_pid"
|
||||
echo "Stopping registered service '$service_name', family $family_name, instance $instance_id with pid=$cmd_pid"
|
||||
kill_processes_by_pid $cmd_pid &
|
||||
fi
|
||||
@ -326,6 +485,7 @@ unregister()
|
||||
kill_flag=1
|
||||
|
||||
if [ -z $service_name ]; then
|
||||
log "unregister" "Error! no service provided for un-registration"
|
||||
echo "Error! no service provided for un-registration"
|
||||
exit 1
|
||||
fi
|
||||
@ -366,6 +526,7 @@ unregister()
|
||||
done
|
||||
fi
|
||||
rm ${FILESYSTEM_PATH}/${TMP_VOL_SRVS_FILE_PRE_STOP}
|
||||
wait
|
||||
else
|
||||
# unregister standard service
|
||||
service="$(cat ${FILESYSTEM_PATH}/${SRVS_FILE} | grep ^${service_name}$)"
|
||||
@ -373,6 +534,11 @@ unregister()
|
||||
log "unregister" "Warning! service '$service_name' is already un-registered"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -z "$(cat ${FILESYSTEM_PATH}/${SRVS_TO_STOP_FILE} | grep ^${service_name}$)" ]; then
|
||||
echo $service >> ${FILESYSTEM_PATH}/${SRVS_TO_STOP_FILE}
|
||||
fi
|
||||
|
||||
if [ $ARCH = "arm" ]; then
|
||||
cmd_pid=$(ps | awk -v srv=${service} '{if($5==srv) print $1}')
|
||||
if [ "${cmd_pid:-null}" = null ] && [ $PIDOF_CMD_EXISTS -eq 1 ]; then
|
||||
@ -386,14 +552,18 @@ unregister()
|
||||
fi
|
||||
if ! [ "${cmd_pid:-null}" = null ]; then
|
||||
log "unregister" "Unregistering $service (pid=$cmd_pid)"
|
||||
echo "Unregistering $service (pid=$cmd_pid)"
|
||||
if [ ${kill_flag} -eq 1 ]; then
|
||||
echo "Stopping registered service '$service' with pid=$cmd_pid"
|
||||
log "unregister" "Stopping registered service '$service' with pid=$cmd_pid"
|
||||
kill_processes_by_pid $cmd_pid
|
||||
fi
|
||||
fi
|
||||
|
||||
grep -v -e "^$service_name$" ${FILESYSTEM_PATH}/${SRVS_FILE} >${FILESYSTEM_PATH}/${TMP_SRVS_FILE}
|
||||
mv ${FILESYSTEM_PATH}/${TMP_SRVS_FILE} ${FILESYSTEM_PATH}/${SRVS_FILE}
|
||||
|
||||
grep -v -e "^$service_name$" ${FILESYSTEM_PATH}/${SRVS_TO_STOP_FILE} >${FILESYSTEM_PATH}/${TMP_SRVS_TO_STOP_FILE}
|
||||
mv ${FILESYSTEM_PATH}/${TMP_SRVS_TO_STOP_FILE} ${FILESYSTEM_PATH}/${SRVS_TO_STOP_FILE}
|
||||
fi
|
||||
}
|
||||
|
||||
@ -446,6 +616,9 @@ rotate_service_log()
|
||||
rotate_service_file ${srv_log_file}
|
||||
done
|
||||
fi
|
||||
if [ -f ${LOG_FILE_PATH}/nano_agent/cp-nano-init-agent.dbg ]; then
|
||||
rotate_service_file ${LOG_FILE_PATH}/nano_agent/cp-nano-init-agent.dbg
|
||||
fi
|
||||
rotate_service_file ${LOG_FILE_PATH}/$LOG_FILE
|
||||
}
|
||||
|
||||
@ -518,9 +691,9 @@ is_service_running()
|
||||
cmd_pid=$(pidof $base_name)
|
||||
fi
|
||||
elif [ $ARCH = "alpine" ]; then
|
||||
cmd_pid=$(ps -ef | awk -v srv="$service" '{if(($4 ~ srv || $3 ~ srv || $6 ~ srv) && ($4 != "awk" && $4 != "grep" )) print $1}')
|
||||
cmd_pid=$(ps -ef | awk -v srv="$service$" '{if(($4 ~ srv || $3 ~ srv || $6 ~ srv) && ($4 != "awk" && $4 != "grep" )) print $1}')
|
||||
else
|
||||
cmd_pid=$(ps -eo pid,cmd | awk -v srv="$service" '{if($2 ~ srv || $3 ~ srv) print $1}')
|
||||
cmd_pid=$(ps -eo pid,cmd | awk -v srv="$service$" '{if($2 ~ srv || $3 ~ srv) print $1}')
|
||||
fi
|
||||
|
||||
if [ "${cmd_pid:-null}" = null ]; then
|
||||
@ -576,8 +749,6 @@ load_volatile_services()
|
||||
family=$(echo $service_line | cut -f2 -d ';')
|
||||
instance_id=$(echo $service_line | cut -f3 -d ';')
|
||||
already_running="0"
|
||||
execution_flags=
|
||||
srv_debug_file=
|
||||
gaia_ld_path=
|
||||
|
||||
if [ -n "$(cat ${FILESYSTEM_PATH}/$SRVS_HALTED | grep $service)" ]; then
|
||||
@ -588,39 +759,22 @@ load_volatile_services()
|
||||
. "${service}.cfg"
|
||||
fi
|
||||
|
||||
if [ -z $family ]; then
|
||||
debug_file_suffix=${instance_id}
|
||||
else
|
||||
debug_file_suffix=${family}_${instance_id}
|
||||
fi
|
||||
|
||||
if [ -z ${srv_debug_file} ]; then
|
||||
base_name=$(get_basename $service)
|
||||
srv_debug_file=${LOG_FILE_PATH}/nano_agent/$base_name.dbg${debug_file_suffix}
|
||||
fi
|
||||
|
||||
if ! [ -z ${gaia_ld_path} ]; then
|
||||
NGEN_LIB_PATH="${USR_LIB_PATH}/cpnano/:${gaia_ld_path}"
|
||||
if [ "$is_smb" = "1" -a "$SUB_HW_VER" = "THX2" ]; then
|
||||
NGEN_LIB_PATH="/lib64:/pfrm2.0/lib64:${NGEN_LIB_PATH}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$(is_volatile_service_running $service $instance_id $family)" = "false"; then
|
||||
family_arg=""
|
||||
if [ -n "${family}" ]; then
|
||||
family_arg="--family=${family}"
|
||||
if [ -n "$(cat ${FILESYSTEM_PATH}/${STARTUP_SRVS_FILE} | grep $service)" ]; then
|
||||
var_service_startup=true
|
||||
grep -v -e "^$service$" ${FILESYSTEM_PATH}/${STARTUP_SRVS_FILE} >${FILESYSTEM_PATH}/${STARTUP_SRVS_FILE}.tmp
|
||||
mv ${FILESYSTEM_PATH}/${STARTUP_SRVS_FILE}.tmp ${FILESYSTEM_PATH}/${STARTUP_SRVS_FILE}
|
||||
else
|
||||
var_service_startup=false
|
||||
fi
|
||||
log "load_volatile_services" "Respawn ${service} ($family : $instance_id)"
|
||||
echo -en "["$(date)"]" >> ${srv_debug_file}
|
||||
eval "LD_LIBRARY_PATH=${NGEN_LIB_PATH} ${service} ${execution_flags} --filesystem_path=${FILESYSTEM_PATH} --log_files_path=${LOG_FILE_PATH} ${family_arg} --id=${instance_id} &"
|
||||
run_volatile_service $service_line $gaia_ld_path
|
||||
increment_watchdog_process_restart_counter
|
||||
echo "running" >> $AGENT_RUN_STATUS_FILE
|
||||
echo "running" > $AGENT_RUN_STATUS_FILE
|
||||
already_running="1"
|
||||
fi
|
||||
|
||||
if test "$already_running" = "0" && [ -f /tmp/agent-status.txt ]; then
|
||||
echo "already running" >>$AGENT_RUN_STATUS_FILE
|
||||
if test "$already_running" = "0" && [ -f $AGENT_RUN_STATUS_FILE ]; then
|
||||
echo "already running" > $AGENT_RUN_STATUS_FILE
|
||||
fi
|
||||
done
|
||||
fi
|
||||
@ -629,6 +783,8 @@ load_volatile_services()
|
||||
load_services()
|
||||
{
|
||||
load_paths
|
||||
|
||||
all_running=true
|
||||
is_startup_mode=false
|
||||
if [ -f ${FILESYSTEM_PATH}/watchdog/wd.startup ]; then
|
||||
rm -f ${FILESYSTEM_PATH}/watchdog/wd.startup
|
||||
@ -638,28 +794,21 @@ load_services()
|
||||
|
||||
already_running="0"
|
||||
for service in $(cat ${FILESYSTEM_PATH}/${SRVS_FILE}); do
|
||||
execution_flags=
|
||||
srv_debug_file=
|
||||
gaia_ld_path=
|
||||
|
||||
if test "$is_startup_mode" = "false" && [ -n "$(cat ${FILESYSTEM_PATH}/$SRVS_HALTED | grep $service)" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -n "$(cat ${FILESYSTEM_PATH}/${SRVS_TO_STOP_FILE} | grep $service)" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -f ${service}.cfg ]; then
|
||||
. "${service}.cfg"
|
||||
fi
|
||||
|
||||
if [ -z ${srv_debug_file} ]; then
|
||||
base_name=$(get_basename $service)
|
||||
srv_debug_file=${LOG_FILE_PATH}/nano_agent/${base_name}.dbg
|
||||
fi
|
||||
|
||||
if ! [ -z ${gaia_ld_path} ]; then
|
||||
NGEN_LIB_PATH="${USR_LIB_PATH}/cpnano/:${gaia_ld_path}"
|
||||
fi
|
||||
|
||||
if test "$(is_service_running $service)" = "false"; then
|
||||
all_running=false
|
||||
|
||||
if [ ! -z $IS_CONTAINER_ENV ] && [ -f ${FILESYSTEM_PATH}/$SRVS_CONTAINER_FILE ]; then
|
||||
if grep -q "$service" ${FILESYSTEM_PATH}/$SRVS_CONTAINER_FILE; then
|
||||
sed -i "/$service/d" ${FILESYSTEM_PATH}/$SRVS_CONTAINER_FILE
|
||||
@ -668,25 +817,35 @@ load_services()
|
||||
fi
|
||||
|
||||
if [ ! -z $IS_CONTAINER_ENV ] && test "$is_startup_mode" = "false"; then
|
||||
log "load_services" "Error: Nano service $service stopped running"
|
||||
echo "Error: Nano service $service stopped running"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "load_services" "Respawn ${service}"
|
||||
if [ "${service}" = "${FILESYSTEM_PATH}/agentCache/cp-nano-agent-cache" ] || [ "${service}" == "/etc/cp/agentIntelligence/redis/redis-server" ] || [ "${service}" = "/etc/cp/crowdsecAux/cp-nano-crowdsec-aux" ]; then
|
||||
eval "LD_LIBRARY_PATH=${NGEN_LIB_PATH} ${service} ${execution_flags} &"
|
||||
if [ -n "$(cat ${FILESYSTEM_PATH}/${STARTUP_SRVS_FILE} | grep $service)" ]; then
|
||||
var_service_startup=true
|
||||
grep -v -e "^$service$" ${FILESYSTEM_PATH}/${STARTUP_SRVS_FILE} >${FILESYSTEM_PATH}/${STARTUP_SRVS_FILE}.tmp
|
||||
mv ${FILESYSTEM_PATH}/${STARTUP_SRVS_FILE}.tmp ${FILESYSTEM_PATH}/${STARTUP_SRVS_FILE}
|
||||
else
|
||||
eval "LD_LIBRARY_PATH=${NGEN_LIB_PATH} ${service} ${execution_flags} --filesystem_path=${FILESYSTEM_PATH} --log_files_path=${LOG_FILE_PATH} &"
|
||||
var_service_startup=false
|
||||
fi
|
||||
run_service $service $gaia_ld_path
|
||||
increment_watchdog_process_restart_counter
|
||||
echo "running" >> $AGENT_RUN_STATUS_FILE
|
||||
echo "running" > $AGENT_RUN_STATUS_FILE
|
||||
already_running="1"
|
||||
fi
|
||||
|
||||
if test "$already_running" = "0" && [ -f /tmp/agent-status.txt ]; then
|
||||
echo "already running" >>$AGENT_RUN_STATUS_FILE
|
||||
if test "$already_running" = "0" && [ -f $AGENT_RUN_STATUS_FILE ]; then
|
||||
echo "already running" > $AGENT_RUN_STATUS_FILE
|
||||
fi
|
||||
done
|
||||
|
||||
if test "$all_running" = "false"; then
|
||||
rm -f /tmp/wd.all_running
|
||||
else
|
||||
touch /tmp/wd.all_running
|
||||
fi
|
||||
}
|
||||
|
||||
get_service_status()
|
||||
@ -716,6 +875,7 @@ get_service_status()
|
||||
shift
|
||||
done
|
||||
if [ -z $service ]; then
|
||||
log "get_service_status" "Error: service name was not provided"
|
||||
echo "Error: service name was not provided"
|
||||
exit 1
|
||||
fi
|
||||
@ -732,6 +892,7 @@ get_service_status()
|
||||
if [ "$verbose" = "true" ]; then
|
||||
echo "service '$service' is ${registration_status} and ${running_status}"
|
||||
else
|
||||
log "get_service_status" "service '$service' is ${registration_status}"
|
||||
echo "service '$service' is ${registration_status}"
|
||||
fi
|
||||
else
|
||||
@ -746,8 +907,10 @@ get_service_status()
|
||||
|
||||
# handle multiple instances services
|
||||
if [ "$verbose" = "true" ]; then
|
||||
log "get_service_status" "service '$service' (Family '$fid', uid '$uid') is ${registration_status} and ${running_status}"
|
||||
echo "service '$service' (Family '$fid', uid '$uid') is ${registration_status} and ${running_status}"
|
||||
else
|
||||
log "get_service_status" "service '$service' (Family '$fid', uid '$uid') is ${registration_status}"
|
||||
echo "service '$service' (Family '$fid', uid '$uid') is ${registration_status}"
|
||||
fi
|
||||
fi
|
||||
@ -770,6 +933,10 @@ elif test "$1" = "--restart_count" || test "$1" = "-rc"; then
|
||||
echo ${counter}
|
||||
exit 0
|
||||
elif test "$1" = "--register" || test "$1" = "-r"; then
|
||||
if test "$2" = "--upgrade"; then
|
||||
var_upgarde=true
|
||||
shift
|
||||
fi
|
||||
if test "$3" = "--family" || test "$3" = "-f"; then
|
||||
family_name=$4
|
||||
if test "$5" = "--count" || test "$5" = "-c"; then
|
||||
@ -844,8 +1011,8 @@ fi
|
||||
IS_SERVICE_STARTED=false
|
||||
echo "" >${FILESYSTEM_PATH}/$SRVS_HALTED
|
||||
while $(true); do
|
||||
if [ -z $IS_CONTAINER_ENV ] && [ -f /tmp/restart_watchdog ]; then
|
||||
rm -f /tmp/restart_watchdog
|
||||
if [ -z $IS_CONTAINER_ENV ] && [ -f ${FILESYSTEM_PATH}/orchestration/restart_watchdog ]; then
|
||||
rm -f ${FILESYSTEM_PATH}/orchestration/restart_watchdog
|
||||
if [ $ARCH = "arm" ]; then
|
||||
cp_exec "$INIT_D_PATH/nano_agent.init restart"
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user