Jul 5th update

This commit is contained in:
Ned Wright
2023-07-05 23:32:39 +00:00
parent 22f1a984aa
commit a59f079ef7
85 changed files with 2488 additions and 1754 deletions

View File

@@ -18,6 +18,7 @@
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
#include <assert.h>
#define MAX_NGINX_UID_LEN 32
#define NUM_OF_NGINX_IPC_ELEMENTS 200
@@ -183,6 +184,10 @@ typedef enum ngx_http_meta_data
CLIENT_ADDR_SIZE,
CLIENT_ADDR_DATA,
CLIENT_PORT,
PARSED_HOST_SIZE,
PARSED_HOST_DATA,
PARSED_URI_SIZE,
PARSED_URI_DATA,
META_DATA_COUNT
} ngx_http_meta_data_e;
@@ -242,6 +247,7 @@ typedef struct __attribute__((__packed__)) ngx_http_cp_web_response_data {
} custom_response_data;
struct __attribute__((__packed__)) ngx_http_cp_redirect_data {
uint8_t unused_dummy;
uint8_t add_event_id;
uint16_t redirect_location_size;
char redirect_location[0];
@@ -249,6 +255,12 @@ typedef struct __attribute__((__packed__)) ngx_http_cp_web_response_data {
} response_data;
} ngx_http_cp_web_response_data_t;
static_assert(
sizeof(((ngx_http_cp_web_response_data_t*)0)->response_data.custom_response_data) ==
sizeof(((ngx_http_cp_web_response_data_t*)0)->response_data.redirect_data),
"custom_response_data must be equal to redirect_data in size"
);
typedef union __attribute__((__packed__)) ngx_http_cp_modify_data {
ngx_http_cp_inject_data_t inject_data[0];
ngx_http_cp_web_response_data_t web_response_data[0];

View File

@@ -20,6 +20,8 @@
#include "i_messaging.h"
#include "i_mainloop.h"
#include "i_time_get.h"
#include "i_agent_details.h"
#include "i_rest_api.h"
#include "component.h"
class IntelligenceComponentV2
@@ -28,6 +30,8 @@ class IntelligenceComponentV2
Singleton::Provide<I_Intelligence_IS_V2>,
Singleton::Consume<I_Messaging>,
Singleton::Consume<I_MainLoop>,
Singleton::Consume<I_AgentDetails>,
Singleton::Consume<I_RestApi>,
Singleton::Consume<I_TimeGet>
{
public:

View File

@@ -21,6 +21,7 @@
#include "i_time_get.h"
#include "i_instance_awareness.h"
#include "component.h"
#include "i_shell_cmd.h"
enum class TenantManagerType { CLIENT, SERVER };
@@ -33,7 +34,8 @@ class TenantManager
Singleton::Consume<I_MainLoop>,
Singleton::Consume<I_TimeGet>,
Singleton::Consume<I_Environment>,
Singleton::Consume<I_RestApi>
Singleton::Consume<I_RestApi>,
Singleton::Consume<I_ShellCmd>
{
public:
TenantManager();

View File

@@ -25,12 +25,25 @@
#include "intelligence_is_v2/intelligence_query_v2.h"
#include "config.h"
namespace Intelligence {
class Invalidation;
} // namespace Intelligence
class I_Intelligence_IS_V2
{
public:
virtual bool sendInvalidation(const Intelligence::Invalidation &invalidation) const = 0;
virtual Maybe<uint> registerInvalidation(
const Intelligence::Invalidation &invalidation,
const std::function<void(const Intelligence::Invalidation &)> &callback
) = 0;
virtual void unregisterInvalidation(uint id) = 0;
template<typename Data>
Maybe<std::vector<AssetReply<Data>>>
queryIntelligence(QueryRequest &query_request)
queryIntelligence(QueryRequest &query_request, bool ignore_in_progress = false, bool is_pretty = true)
{
uint assets_limit = query_request.getAssetsLimit();
static const uint upper_assets_limit = 50;
@@ -50,7 +63,7 @@ public:
return genError("Paging is activated and already finished. No need for more queries.");
}
IntelligenceQuery<Data> intelligence_query(query_request);
IntelligenceQuery<Data> intelligence_query(query_request, is_pretty);
static const std::string query_uri = "/api/v2/intelligence/assets/query";
bool res = getIsOfflineOnly() ? false : sendQueryObject(intelligence_query, query_uri, assets_limit);
@@ -67,12 +80,15 @@ public:
}
}
if (ignore_in_progress && intelligence_query.getResponseStatus() == ResponseStatus::IN_PROGRESS) {
return genError("Query intelligence response with InProgress status");
}
return intelligence_query.getData();
}
template<typename Data>
Maybe<std::vector<Maybe<std::vector<AssetReply<Data>>>>>
queryIntelligence(std::vector<QueryRequest> &query_requests)
queryIntelligence(std::vector<QueryRequest> &query_requests, bool is_pretty = true)
{
static const uint upper_assets_limit = 50;
static const uint upper_confidence_limit = 1000;
@@ -95,7 +111,7 @@ public:
);
}
}
IntelligenceQuery<Data> intelligence_query(query_requests);
IntelligenceQuery<Data> intelligence_query(query_requests, is_pretty);
static const std::string query_uri = "/api/v2/intelligence/assets/queries";
dbgTrace(D_INTELLIGENCE) << "Sending intelligence bulk request with " << query_requests.size() << " items";

View File

@@ -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.
#ifndef __I_MESSAGING_DOWNLOADER_H__
#define __I_MESSAGING_DOWNLOADER_H__
#include <string>
#include <functional>
#include "maybe_res.h"
class I_MessagingDownloader
{
public:
using OnCompleteCB = std::function<void(const Maybe<std::string> &)>;
virtual bool downloadFile(
const std::string &file_name,
const std::string &url,
OnCompleteCB cb = nullptr,
const unsigned int port = 0
) = 0;
protected:
virtual ~I_MessagingDownloader() {}
};
#endif // __I_MESSAGING_DOWNLOADER_H__

View File

@@ -48,6 +48,8 @@ public:
return addRestCall(oper, uri, std::make_unique<SpecificRestInit<T>>());
}
virtual uint16_t getListeningPort() const = 0;
protected:
~I_RestApi() {}
virtual bool addRestCall(RestAction oper, const std::string &uri, std::unique_ptr<RestInit> &&init) = 0;

View File

@@ -21,12 +21,11 @@
#include <chrono>
#include <functional>
#include "tenant_profile_pair.h"
class I_TenantManager
{
public:
using newTenantCB = std::function<void(const std::vector<std::string> &)>;
virtual void uponNewTenants(const newTenantCB &cb) = 0;
virtual bool areTenantAndProfileActive(const std::string &tenant_id, const std::string &profile_id) const = 0;
virtual std::set<std::string> fetchAllActiveTenants() const = 0;
@@ -36,14 +35,13 @@ public:
const std::string &profile_id
) const = 0;
virtual std::map<std::string, std::set<std::string>> fetchActiveTenantsAndProfiles() const = 0;
virtual std::map<std::string, std::set<std::string>> fetchAndUpdateActiveTenantsAndProfiles(bool update) = 0;
virtual std::set<std::string> fetchProfileIds(const std::string &tenant_id) const = 0;
virtual void deactivateTenant(const std::string &tenant_id, const std::string &profile_id) = 0;
virtual void addActiveTenantAndProfile(const std::string &tenant_id, const std::string &profile_id) = 0;
virtual std::chrono::microseconds getTimeoutVal() const = 0;
virtual std::set<std::string> getProfileIdsForRegionAccount(
const std::string &tenant_id,
const std::string &region,

View File

@@ -27,20 +27,22 @@ template <typename UserSerializableReplyAttr>
class IntelligenceQuery
{
public:
IntelligenceQuery(QueryRequest &filter)
IntelligenceQuery(QueryRequest &filter, bool is_pretty)
:
request(filter),
response(),
responses(),
is_bulk(false)
is_bulk(false),
is_pretty(is_pretty)
{}
IntelligenceQuery(std::vector<QueryRequest> &filters)
IntelligenceQuery(std::vector<QueryRequest> &filters, bool is_pretty)
:
requests(filters),
response(),
responses(),
is_bulk(true)
is_bulk(true),
is_pretty(is_pretty)
{}
Maybe<std::string> genJson() const;
@@ -67,6 +69,7 @@ private:
IntelligenceQueryResponse<UserSerializableReplyAttr> response;
std::vector<IntelligenceQueryResponse<UserSerializableReplyAttr>> responses;
bool is_bulk;
bool is_pretty;
};
#include "intelligence_query_v2_impl.h"

View File

@@ -18,6 +18,9 @@
#error intelligence_query_impl_v2.h should not be included directly!
#endif // __INTELLIGENCE_QUERY_V2_H__
#include <sstream>
#include "json_stream.h"
USE_DEBUG_FLAG(D_INTELLIGENCE);
template <typename UserSerializableReplyAttr>
@@ -32,9 +35,10 @@ Maybe<std::string>
IntelligenceQuery<UserSerializableReplyAttr>::genJson() const
{
{
std::stringstream out;
std::stringstream str_stream;
JsonStream json_stream(&str_stream, is_pretty);
{
cereal::JSONOutputArchive out_ar(out);
cereal::JSONOutputArchive out_ar(json_stream);
if (is_bulk) {
std::vector<BulkQueryRequest> bulk_requests;
int index = 0;
@@ -46,7 +50,8 @@ IntelligenceQuery<UserSerializableReplyAttr>::genJson() const
request.saveToJson(out_ar);
}
}
return out.str();
return str_stream.str();
}
}

View File

@@ -43,7 +43,9 @@ enum class Condition
STARTS_WITH,
CONTAINS,
IN,
NOT_IN
NOT_IN,
GREATER_THAN,
LESS_THAN
};
enum class CursorState {

View File

@@ -0,0 +1,35 @@
// Copyright (C) 2023 Check Point Software Technologies Ltd. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __JSON_STREAM_H__
#define __JSON_STREAM_H__
#include <ostream>
class JsonStream : public std::streambuf, public std::ostream
{
public:
JsonStream(std::ostream *os, bool is_pretty);
private:
int overflow(int c) override;
void emplace(char c);
void add(char c);
std::ostream *os;
bool is_prev_single_backslash = false;
bool is_pretty;
bool in_string = false;
};
#endif // __JSON_STREAM_H__

View File

@@ -14,6 +14,7 @@
#ifndef __QUERY_FILTER_V2_H__
#define __QUERY_FILTER_V2_H__
#include <boost/variant.hpp>
#include <string>
#include <chrono>
#include <boost/functional/hash.hpp>
@@ -29,6 +30,8 @@ using namespace Intelligence_IS_V2;
class SerializableQueryCondition
{
public:
typedef boost::variant<int64_t, std::string> ValueVariant;
SerializableQueryCondition() {}
SerializableQueryCondition(Condition _condition_type, std::string _key, std::string _value)
@@ -36,18 +39,25 @@ public:
condition_type(_condition_type),
key(_key),
value(_value)
{};
{}
SerializableQueryCondition(Condition _condition_type, std::string _key, int64_t _value)
:
condition_type(_condition_type),
key(_key),
value(_value)
{}
void save(cereal::JSONOutputArchive &ar) const;
Condition getConditionType() const { return condition_type; }
const std::string & getKey() const { return key; }
const std::string & getValue() const { return value; }
const ValueVariant & getValue() const { return value; }
private:
Condition condition_type = Condition::EQUALS;
std::string key = "";
std::string value = "";
ValueVariant value = "";
};
class SerializableQueryFilter
@@ -55,22 +65,18 @@ class SerializableQueryFilter
public:
SerializableQueryFilter() {}
SerializableQueryFilter(Condition condition_type, const std::string &key, const std::string &value);
SerializableQueryFilter(
Operator operator_type,
Condition condition_type,
const std::string &key,
const std::string &value
);
SerializableQueryFilter(Condition condition_type, const std::string &key, const int64_t &value);
void save(cereal::JSONOutputArchive &ar) const;
void addCondition(Condition condition_type, const std::string &key, const std::string &value);
void addCondition(Condition condition_type, const std::string &key, const int64_t &value);
Operator getOperator() const { return operator_type; }
const std::vector<SerializableQueryCondition> & getConditionOperands() const { return condition_operands; }
const std::vector<SerializableQueryFilter> & getQueriesOperands() const { return queries_operands; }
const std::string & getConditionValueByKey(const std::string &key) const;
Maybe<SerializableQueryCondition::ValueVariant> getConditionValueByKey(const std::string &key) const;
bool empty() const { return condition_operands.empty() && queries_operands.empty(); }
@@ -80,7 +86,8 @@ public:
private:
void saveCondition(cereal::JSONOutputArchive &ar) const;
void saveOperation(cereal::JSONOutputArchive &ar) const;
SerializableQueryFilter calcOperator(const SerializableQueryFilter &other_query, const Operator &operator_type);
bool isOperatorComp(const Operator &oper) const;
SerializableQueryFilter calcOperator(const SerializableQueryFilter &other_query, const Operator &oper);
Operator operator_type = Operator::NONE;
std::vector<SerializableQueryFilter> queries_operands = {};

View File

@@ -37,6 +37,14 @@ public:
AttributeKeyType type = AttributeKeyType::MAIN
);
QueryRequest(
Condition condition_type,
const std::string &key,
const int64_t &value,
bool full_response,
AttributeKeyType type = AttributeKeyType::MAIN
);
void saveToJson(cereal::JSONOutputArchive &ar) const;
void save(cereal::JSONOutputArchive &ar) const;
@@ -51,6 +59,13 @@ public:
AttributeKeyType attribute_type = AttributeKeyType::MAIN
);
void addCondition(
Condition condition_type,
const std::string &key,
const int64_t &value,
AttributeKeyType attribute_type = AttributeKeyType::MAIN
);
void setRequestedAttr(
const std::string &attr,
AttributeKeyType attribute_type = AttributeKeyType::REGULAR

View File

@@ -8,6 +8,7 @@
class MockRestApi : public Singleton::Provide<I_RestApi>::From<MockProvider<I_RestApi>>
{
public:
MOCK_CONST_METHOD0(getListeningPort, uint16_t());
// You can't mock a function with an R-value reference. So mock a slightly different one
MOCK_METHOD3(mockRestCall, bool(RestAction, const std::string &, const std::unique_ptr<RestInit> &));

View File

@@ -13,8 +13,6 @@
class MockTenantManager : public Singleton::Provide<I_TenantManager>::From<MockProvider<I_TenantManager>>
{
public:
MOCK_METHOD1(uponNewTenants, void(const I_TenantManager::newTenantCB &cb));
MOCK_CONST_METHOD0(fetchActiveTenantsAndProfiles, std::map<std::string, std::set<std::string>>());
MOCK_CONST_METHOD0(fetchActiveTenants, std::set<std::string>());
MOCK_CONST_METHOD0(fetchAllActiveTenants, std::set<std::string>());
@@ -26,13 +24,11 @@ public:
MOCK_CONST_METHOD2(areTenantAndProfileActive, bool(const std::string &, const std::string &));
MOCK_METHOD2(addActiveTenantAndProfile, void(const std::string &, const std::string &));
MOCK_METHOD2(deactivateTenant, void(const std::string &, const std::string &));
MOCK_METHOD1(fetchAndUpdateActiveTenantsAndProfiles, std::map<std::string, std::set<std::string>>(bool));
MOCK_CONST_METHOD3(
getProfileIdsForRegionAccount,
std::set<std::string>(const std::string &, const std::string &, const std::string &)
);
MOCK_CONST_METHOD0(getTimeoutVal, std::chrono::microseconds());
private:
MOCK_METHOD3(
addInstance,

View File

@@ -90,6 +90,7 @@ std::string getConfigurationFlagWithDefault(const std::string &default_val, cons
const std::string & getFilesystemPathConfig();
const std::string & getLogFilesPathConfig();
void clearOldTenants();
std::string getPolicyConfigPath(
const std::string &name,

View File

@@ -155,7 +155,7 @@ Maybe<SettingType, Config::Errors>
getProfileAgentSetting(const std::string &setting)
{
auto i_config = Singleton::Consume<Config::I_Config>::from<Config::MockConfigProvider>();
const std::string &value = i_config->getProfileAgentSetting(setting);
std::string value = i_config->getProfileAgentSetting(setting);
if (value.empty()) return TypeWrapper::failMissing<SettingType>();

View File

@@ -39,7 +39,7 @@ public:
virtual PerContextValue getAllConfiguration(const std::vector<std::string> &paths) const = 0;
virtual const TypeWrapper & getResource(const std::vector<std::string> &paths) const = 0;
virtual const TypeWrapper & getSetting(const std::vector<std::string> &paths) const = 0;
virtual const string & getProfileAgentSetting(const string &setting_name) const = 0;
virtual string getProfileAgentSetting(const string &setting_name) const = 0;
virtual vector<string> getProfileAgentSettings(const string &setting_name_regex) const = 0;
virtual const string & getConfigurationFlag(const string &flag_name) const = 0;
@@ -104,6 +104,8 @@ public:
virtual void registerConfigLoadCb(ConfigCb) = 0;
virtual void registerConfigAbortCb(ConfigCb) = 0;
virtual void clearOldTenants() = 0;
protected:
virtual ~I_Config() {}
};

View File

@@ -148,6 +148,7 @@ DEFINE_FLAG(D_COMPONENT, D_ALL)
DEFINE_FLAG(D_IOT_QUERY_INTELLIGENCE, D_IOT_AUXILIARY)
DEFINE_FLAG(D_IOT_SAVE_PERSISTENT, D_IOT_AUXILIARY)
DEFINE_FLAG(D_IOT_DOCKER, D_IOT_AUXILIARY)
DEFINE_FLAG(D_IOT_REST_AUTHENTICATION, D_IOT_AUXILIARY)
DEFINE_FLAG(D_IOT_ENFORCE, D_IOT_NEXT)
DEFINE_FLAG(D_IOT_ENFORCE_POLICY, D_IOT_ENFORCE)
DEFINE_FLAG(D_IOT_ENFORCE_ASSETS, D_IOT_ENFORCE)
@@ -156,6 +157,7 @@ DEFINE_FLAG(D_COMPONENT, D_ALL)
DEFINE_FLAG(D_IOT_QUERY_ASSETS, D_IOT_RISK)
DEFINE_FLAG(D_IOT_INDICATOR_DATA, D_IOT_RISK)
DEFINE_FLAG(D_IOT_INDICATORS, D_IOT_RISK)
DEFINE_FLAG(D_IOT_DOCKER_WATCHDOG, D_IOT_RISK)
DEFINE_FLAG(D_IOT_DISCOVERY, D_IOT_NEXT)
DEFINE_FLAG(D_IOT_PROBE, D_IOT_DISCOVERY)
DEFINE_FLAG(D_IOT_ASSETS_DATA, D_IOT_DISCOVERY)

View File

@@ -0,0 +1,74 @@
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __INTELLIGENCE_INVALIDATION_H__
#define __INTELLIGENCE_INVALIDATION_H__
#include <functional>
#include <map>
#include <string>
#include <set>
#include "maybe_res.h"
#include "enum_array.h"
class I_Intelligence_IS_V2;
namespace Intelligence
{
enum class ClassifierType { CLASS, CATEGORY, FAMILY, GROUP, ORDER, KIND };
enum class ObjectType { ASSET, ZONE, POLICY_PACKAGE, CONFIGURATION, SESSION };
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);
Invalidation & setStringSetAttr(const std::string &attr, const std::set<std::string> &val);
Invalidation & setSourceId(const std::string &id);
Invalidation & setObjectType(ObjectType type);
std::string getClassifier(ClassifierType type) const { return classifiers[type]; }
Maybe<std::string, void> getStringAttr(const std::string &attr) const;
Maybe<std::set<std::string>, void> getStringSetAttr(const std::string &attr) const;
const Maybe<std::string, void> & getSourceId() const { return source_id; }
const Maybe<ObjectType, void> & getObjectType() const { return object_type; }
bool report(I_Intelligence_IS_V2 *interface) const;
Maybe<uint> startListening(I_Intelligence_IS_V2 *interface, const std::function<void(const Invalidation &)> &cb);
void stopListening(I_Intelligence_IS_V2 *interface);
Maybe<std::string> genJson() const;
std::string genObject() const;
bool isLegalInvalidation() const;
bool matches(const Invalidation &other) const;
private:
bool hasAttr(const std::string &key, const std::string &value) 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;
Maybe<std::string, void> source_id;
Maybe<ObjectType, void> object_type;
Maybe<uint, void> listening_id;
};
} // namespace Intelligence
#endif // __INTELLIGENCE_INVALIDATION_H__

View File

@@ -25,8 +25,6 @@
#include "debug.h"
#include "flags.h"
#include "config.h"
#include "virtual_container.h"
#include "Log_modifiers.h"
enum class LogFieldOption { XORANDB64, COUNT };
@@ -111,14 +109,53 @@ class LogField : Singleton::Consume<I_Environment>
getSyslogAndCef() const override
{
std::string value(Details::getValueAsString(getValue()));
auto modifier1 = makeVirtualContainer<LogModifiers::ReplaceBackslash>(value);
auto modifier2 = makeVirtualContainer<LogModifiers::ReplaceCR>(modifier1);
auto modifier3 = makeVirtualContainer<LogModifiers::ReplaceLF>(modifier2);
auto modifier4 = makeVirtualContainer<LogModifiers::ReplaceDoubleOuotes>(modifier3);
auto modifier5 = makeVirtualContainer<LogModifiers::ReplaceQuote>(modifier4);
auto modifier6 = makeVirtualContainer<LogModifiers::ReplaceClosingBrace>(modifier5);
auto modifier7 = makeVirtualContainer<LogModifiers::ReplaceEqualSign>(modifier6);
return name + "=\"" + std::string(modifier7.begin(), modifier7.end()) + "\"";
std::string encoded_value;
encoded_value.reserve(value.size() + 6);
for (char ch : value) {
switch (ch) {
case '\\': {
encoded_value.push_back('\\');
encoded_value.push_back('\\');
break;
}
case '\n': {
encoded_value.push_back('\\');
encoded_value.push_back('n');
break;
}
case '\r': {
encoded_value.push_back('\\');
encoded_value.push_back('r');
break;
}
case '"': {
encoded_value.push_back('\\');
encoded_value.push_back('"');
break;
}
case '\'': {
encoded_value.push_back('\\');
encoded_value.push_back('\'');
break;
}
case ']': {
encoded_value.push_back('\\');
encoded_value.push_back(']');
break;
}
case '=': {
encoded_value.push_back('\\');
encoded_value.push_back('=');
break;
}
default: {
encoded_value.push_back(ch);
}
}
}
return name + "=\"" + encoded_value + "\"";
}
// LCOV_EXCL_START Reason: seems that assert prevent the LCOV from identifying that method was tested

View File

@@ -63,6 +63,8 @@ enum class Tags {
DEPLOYMENT_K8S,
LAYER_7_ACCESS_CONTROL,
HORIZON_TELEMETRY_METRICS,
CROWDSEC,
PLAYGROUND,
COUNT
};

View File

@@ -20,6 +20,8 @@
#include "cereal/types/vector.hpp"
#include "cereal/archives/json.hpp"
#include "rest/schema_printer.h"
template <typename ... Types>
class SerializableMultiMap : std::map<std::string, Types> ...
{
@@ -40,6 +42,27 @@ public:
}
}
void clear() { clear(Types()...); }
template <typename T>
std::map<std::string, T> &
getMap()
{
return static_cast<std::map<std::string, T> &>(*this);
}
void
performOutputingSchema(std::ostream &out, int level)
{
RestHelper::printIndent(out, level) << "\"additionalProperties\": {\n";
RestHelper::printIndent(out, level + 1) << "\"anyOf\": [";
printTypes<Types...>(out, level +2, 0);
out << '\n';
RestHelper::printIndent(out, level + 1) << "]\n";
RestHelper::printIndent(out, level) << "}";
}
private:
template <typename Archive, typename T, typename ... More>
void
load(const std::string &key, Archive &archive, T t, More ... more)
@@ -59,20 +82,29 @@ public:
std::map<std::string, T>::operator[](key) = t;
}
void clear() { clear(Types()...); }
template <typename T, typename ... More>
void clear(const T &t, const More & ... more) { clear(t); clear(more...); }
template <typename T>
void clear(const T &) { std::map<std::string, T>::clear(); }
template <typename T, typename ... More>
void
printTypes(std::ostream &out, int level, uint)
{
printTypes<T>(out, level, 0);
out << ",";
printTypes<More...>(out, level, 0);
}
template <typename T>
std::map<std::string, T> &
getMap()
void
printTypes(std::ostream &out, int level, int)
{
return static_cast<std::map<std::string, T> &>(*this);
out << '\n';
RestHelper::printIndent(out, level) << "{\n";
TypeDector<T>::type(out, level + 1);
RestHelper::printIndent(out, level) << "}";
}
};