Skip to content

Commit

Permalink
FilterUtility::GetFilterTargets(): don't run filter for specific obje…
Browse files Browse the repository at this point in the history
…ct(s) for all objects
  • Loading branch information
Al2Klimov committed Dec 13, 2023
1 parent 15191bc commit ecfc903
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 10 deletions.
4 changes: 2 additions & 2 deletions lib/config/applyrule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class ApplyRule : public SharedObject
static const std::vector<ApplyRule::Ptr>& GetRules(const Type::Ptr& sourceType, const Type::Ptr& targetType);
static const std::set<ApplyRule::Ptr>& GetTargetedHostRules(const Type::Ptr& sourceType, const String& host);
static const std::set<ApplyRule::Ptr>& GetTargetedServiceRules(const Type::Ptr& sourceType, const String& host, const String& service);
static bool GetTargetHosts(Expression* assignFilter, std::vector<const String *>& hosts, const Dictionary::Ptr& constants = nullptr);
static bool GetTargetServices(Expression* assignFilter, std::vector<std::pair<const String *, const String *>>& services, const Dictionary::Ptr& constants = nullptr);

static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes);
static bool IsValidSourceType(const String& sourceType);
Expand All @@ -108,8 +110,6 @@ class ApplyRule : public SharedObject
static RuleMap m_Rules;

static bool AddTargetedRule(const ApplyRule::Ptr& rule, const String& targetType, PerSourceType& rules);
static bool GetTargetHosts(Expression* assignFilter, std::vector<const String *>& hosts, const Dictionary::Ptr& constants = nullptr);
static bool GetTargetServices(Expression* assignFilter, std::vector<std::pair<const String *, const String *>>& services, const Dictionary::Ptr& constants = nullptr);
static std::pair<const String *, const String *> GetTargetService(Expression* assignFilter, const Dictionary::Ptr& constants);
static const String * GetComparedName(Expression* assignFilter, const char * lcType, const Dictionary::Ptr& constants);
static bool IsNameIndexer(Expression* exp, const char * lcType, const Dictionary::Ptr& constants);
Expand Down
72 changes: 64 additions & 8 deletions lib/remote/filterutility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "remote/filterutility.hpp"
#include "remote/httputility.hpp"
#include "config/applyrule.hpp"
#include "config/configcompiler.hpp"
#include "config/expression.hpp"
#include "base/namespace.hpp"
Expand Down Expand Up @@ -271,18 +272,73 @@ std::vector<Value> FilterUtility::GetFilterTargets(const QueryDescription& qd, c
if (query->Contains("filter")) {
String filter = HttpUtility::GetLastParameter(query, "filter");
std::unique_ptr<Expression> ufilter = ConfigCompiler::CompileText("<API query>", filter);

Dictionary::Ptr filter_vars = query->Get("filter_vars");
if (filter_vars) {
ObjectLock olock(filter_vars);
for (const Dictionary::Pair& kv : filter_vars) {
frameNS->Set(kv.first, kv.second);
bool targeted = false;
std::vector<ConfigObject::Ptr> targets;

if (dynamic_cast<ConfigObjectTargetProvider*>(provider.get())) {
auto dict (dynamic_cast<DictExpression*>(ufilter.get()));

if (dict) {
auto& subex (dict->GetExpressions());

if (subex.size() == 1u) {
if (type == "Host") {
std::vector<const String *> targetNames;

if (ApplyRule::GetTargetHosts(subex.at(0).get(), targetNames, filter_vars)) {
static const auto typeHost (Type::GetByName("Host"));
static const auto ctypeHost (dynamic_cast<ConfigType*>(typeHost.get()));
targeted = true;

for (auto name : targetNames) {
auto target (ctypeHost->GetObject(*name));

if (target) {
targets.emplace_back(target);
}
}
}
} else if (type == "Service") {
std::vector<std::pair<const String *, const String *>> targetNames;

if (ApplyRule::GetTargetServices(subex.at(0).get(), targetNames, filter_vars)) {
static const auto typeService (Type::GetByName("Service"));
static const auto ctypeService (dynamic_cast<ConfigType*>(typeService.get()));
targeted = true;

for (auto name : targetNames) {
auto target (ctypeService->GetObject(*name.first + "!" + *name.second));

if (target) {
targets.emplace_back(target);
}
}
}
}
}
}
}

provider->FindTargets(type, [&permissionFrame, &permissionFilter, &frame, &ufilter, &result, variableName](const Object::Ptr& target) {
FilteredAddTarget(permissionFrame, permissionFilter.get(), frame, &*ufilter, result, variableName, target);
});
if (targeted) {
for (auto& target : targets) {
if (FilterUtility::EvaluateFilter(permissionFrame, permissionFilter.get(), target, variableName)) {
result.emplace_back(std::move(target));
}
}
} else {
if (filter_vars) {
ObjectLock olock (filter_vars);

for (auto& kv : filter_vars) {
frameNS->Set(kv.first, kv.second);
}
}

provider->FindTargets(type, [&permissionFrame, &permissionFilter, &frame, &ufilter, &result, variableName](const Object::Ptr& target) {
FilteredAddTarget(permissionFrame, permissionFilter.get(), frame, &*ufilter, result, variableName, target);
});
}
} else {
/* Ensure to pass a nullptr as filter expression.
* GCC 8.1.1 on F28 causes problems, see GH #6533.
Expand Down

0 comments on commit ecfc903

Please sign in to comment.