Currently EQL requires at least one index to match in order to validate the query. However just like search, the allow_no_indices option is permitted which leads to confusing behavior since it can be true, yet EQL will throw an exception:
### A
GET foo*/_search
# success
GET foo*/_eql/search
{
"size": 0,
"query": "process where 1 == 1"
}
# "type" : "index_not_found_exception",
# "reason" : "no such index [foo*]",
### B
GET foo/_search?ignore_unavailable=true
# success
GET foo/_eql/search?ignore_unavailable=true
{
"size": 0,
"query": "process where 1 == 1"
}
# "type" : "index_not_found_exception",
# "reason" : "no such index [[foo]]",
### C
GET foo/_search
# "type" : "index_not_found_exception",
# "reason" : "no such index [foo]",
GET foo/_eql/search
{
"size": 0,
"query": "process where 1 == 1"
}
# "type" : "mapping_exception",
# "reason" : "Unknown index [foo]",
### D
GET foo*/_search?allow_no_indices=false
# "type" : "index_not_found_exception",
# "reason" : "no such index [foo*]",
GET foo*/_eql/search?allow_no_indices=false
{
"size": 0,
"query": "process where 1 == 1"
}
# "type" : "index_not_found_exception",
# "reason" : "no such index [foo*]",
GET foo*/_eql/search?allow_no_indices=true
{
"size": 0,
"query": "process where 1 == 1"
}
# "type" : "mapping_exception",
# "reason" : "Unknown index [*,-*]"
Considering the similarities to the search API, EQL should either provide a similar behavior or not accept this parameter.
Pinging @elastic/es-ql (:Query Languages/EQL)
/cc @rylnd
@costin in addition to the above discrepancies, I wanted to note that allow_no_indices does provide behavior on which EQL rules currently depend: it overrides the default behavior of a query with multiple indexes failing if any of them do not resolve.
GET auditbeat-*,foo*/_eql/search
// index_not_found_exception: no such index [foo*]
GET auditbeat-*,foo*/_eql/search?allow_no_indices=true
// success
Since a default detection rule will be populated with security solution's default indices (some of which may or may not exist/be visible for the rule writer), and since the default behavior for an ES search is to ignore these unmatched patterns, the ability to replicate this behavior in EQL would be ideal.
@rylnd I've finally gotten around to look at this. There are two options relevant to you on index resolution:
allow_no_indices which in ES is true by default however in EQL it has to be false since at least one mapping is needed to validate the query.ignore_unavailable which in ES is true by default but in EQL was false. That is why a combination of non-existing index/pattern plus an existing one failed. I've changed the default to true so it is possible to query indexA,missingIndex without getting an exception.Note the associated PR only fixes the defaults, you can get the same behavior right now by adding ignore_unavailable=true to the request since EQL does parse index options.
@costin thanks for looking into this! I agree with your assessment of allow_no_indices, we don't really have a need for that behavior, I think it was being conflated with ignore_unavailable due to the behavior exhibited in my previous comment.
While I agree with your statements about how ignore_unavailable should behave, I want to verify that changing the defaults is all that's needed, since I seem to be seeing different behavior than what is described:
GET auditbeat-*,foo*/_eql/search
// index_not_found_exception: no such index [foo*]
GET auditbeat-*,foo*/_eql/search?ignore_unavailable=true
// index_not_found_exception: no such index [foo*]
GET auditbeat-*,foo*/_eql/search?allow_no_indices=true
// success
This seems to be due to the wildcard index, since if I specify a concrete index ignore_unavailable functions as you describe:
GET auditbeat-*,foo*/_eql/search?ignore_unavailable=true
// index_not_found_exception: no such index [foo*]
GET auditbeat-*,foo/_eql/search?ignore_unavailable=true
// success
This might be still on us due to the way we resolve the wildcard pattern.
@rylnd I've added two integration tests for non existing indices, one with a non-existing index another one with a non-matching pattern and they are passing.
Once the PR gets merged, can you please try out the snapshot and see whether the issue still appears.
@costin I was able to test this on the latest snapshot (fcbbc7e7967). While the defaults look to be updated (I no longer have to specify ignore_unavailable), the aforementioned issue with wildcard indexes is still present:
GET auditbeat-*,foo*/_eql/search
// index_not_found_exception: no such index [foo*]
GET auditbeat-*,foo/_eql/search
// success
This is undesirable for the kibana security app in particular, as the app's default indexes (and thus the defaults for these queries) all include wildcards. Rule creators can perform a normal ES query across all these indexes regardless of access/existence, while they would need to explicitly exclude from their EQL query those that they can't see.
Most helpful comment
@costin in addition to the above discrepancies, I wanted to note that
allow_no_indicesdoes provide behavior on which EQL rules currently depend: it overrides the default behavior of a query with multiple indexes failing if any of them do not resolve.Since a default detection rule will be populated with security solution's default indices (some of which may or may not exist/be visible for the rule writer), and since the default behavior for an ES search is to ignore these unmatched patterns, the ability to replicate this behavior in EQL would be ideal.