-
Notifications
You must be signed in to change notification settings - Fork 25.6k
EQL: implement cidrMatch function #54186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
aff0389
ee76e7c
439cbc2
16ff57d
0e4280d
5056054
b1342e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| { | ||
| "properties" : { | ||
| "command_line" : { | ||
| "type" : "keyword" | ||
| }, | ||
| "event" : { | ||
| "properties" : { | ||
| "category" : { | ||
| "type" : "keyword" | ||
| } | ||
| } | ||
| }, | ||
| "md5" : { | ||
| "type" : "keyword" | ||
| }, | ||
| "parent_process_name": { | ||
| "type" : "keyword" | ||
| }, | ||
| "parent_process_path": { | ||
| "type" : "keyword" | ||
| }, | ||
| "pid" : { | ||
| "type" : "long" | ||
| }, | ||
| "ppid" : { | ||
| "type" : "long" | ||
| }, | ||
| "process_name": { | ||
| "type" : "keyword" | ||
| }, | ||
| "process_path": { | ||
| "type" : "keyword" | ||
| }, | ||
| "subtype" : { | ||
| "type" : "keyword" | ||
| }, | ||
| "@timestamp" : { | ||
| "type" : "date" | ||
| }, | ||
| "user" : { | ||
| "type" : "keyword" | ||
| }, | ||
| "user_name" : { | ||
| "type" : "keyword" | ||
| }, | ||
| "user_domain": { | ||
| "type" : "keyword" | ||
| }, | ||
| "hostname" : { | ||
| "type" : "text", | ||
| "fields" : { | ||
| "keyword" : { | ||
| "type" : "keyword", | ||
| "ignore_above" : 256 | ||
| } | ||
| } | ||
| }, | ||
| "opcode" : { | ||
| "type" : "long" | ||
| }, | ||
| "file_name" : { | ||
| "type" : "text", | ||
| "fields" : { | ||
| "keyword" : { | ||
| "type" : "keyword", | ||
| "ignore_above" : 256 | ||
| } | ||
| } | ||
| }, | ||
| "serial_event_id" : { | ||
| "type" : "long" | ||
| }, | ||
| "source_address" : { | ||
| "type" : "ip" | ||
| }, | ||
| "exit_code" : { | ||
| "type" : "long" | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |
|
|
||
| package org.elasticsearch.xpack.eql.expression.function; | ||
|
|
||
| import org.elasticsearch.xpack.eql.expression.function.scalar.string.CIDRMatch; | ||
| import org.elasticsearch.xpack.eql.expression.function.scalar.string.Substring; | ||
| import org.elasticsearch.xpack.ql.expression.function.FunctionDefinition; | ||
| import org.elasticsearch.xpack.ql.expression.function.FunctionRegistry; | ||
|
|
@@ -24,6 +25,7 @@ private static FunctionDefinition[][] functions() { | |
| // String | ||
| new FunctionDefinition[] { | ||
| def(Substring.class, Substring::new, "substring"), | ||
| def(CIDRMatch.class, CIDRMatch::new, "cidrmatch"), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer listing the functions in alphabetical order.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep. Updated. |
||
| }, | ||
| }; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,108 @@ | ||||||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||||||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||||||||||||||||||||||||||||
| * or more contributor license agreements. Licensed under the Elastic License; | ||||||||||||||||||||||||||||
| * you may not use this file except in compliance with the Elastic License. | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| package org.elasticsearch.xpack.eql.expression.function.scalar.string; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| import org.elasticsearch.xpack.ql.expression.Expression; | ||||||||||||||||||||||||||||
| import org.elasticsearch.xpack.ql.expression.Expressions; | ||||||||||||||||||||||||||||
| import org.elasticsearch.xpack.ql.expression.Expressions.ParamOrdinal; | ||||||||||||||||||||||||||||
| import org.elasticsearch.xpack.ql.expression.function.scalar.ScalarFunction; | ||||||||||||||||||||||||||||
| import org.elasticsearch.xpack.ql.expression.gen.script.ScriptTemplate; | ||||||||||||||||||||||||||||
| import org.elasticsearch.xpack.ql.expression.predicate.logical.Or; | ||||||||||||||||||||||||||||
| import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.Equals; | ||||||||||||||||||||||||||||
| import org.elasticsearch.xpack.ql.tree.NodeInfo; | ||||||||||||||||||||||||||||
| import org.elasticsearch.xpack.ql.tree.Source; | ||||||||||||||||||||||||||||
| import org.elasticsearch.xpack.ql.type.DataType; | ||||||||||||||||||||||||||||
| import org.elasticsearch.xpack.ql.type.DataTypes; | ||||||||||||||||||||||||||||
| import org.elasticsearch.xpack.ql.util.CollectionUtils; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| import static java.util.Collections.singletonList; | ||||||||||||||||||||||||||||
| import static org.elasticsearch.xpack.ql.expression.TypeResolutions.isIPAndExact; | ||||||||||||||||||||||||||||
| import static org.elasticsearch.xpack.ql.expression.TypeResolutions.isStringAndExact; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * EQL specific cidrMatch function | ||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Personal preference, but I would like to see a useful description of the function. Not even the original EQL documentation is clear imo: https://eql.readthedocs.io/en/latest/query-guide/functions.html
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a couple of more lines with a link to the EQL doc. |
||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| public class CIDRMatch extends ScalarFunction { | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| private final Expression field; | ||||||||||||||||||||||||||||
| private final List<Expression> addresses; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| public CIDRMatch(Source source, Expression field, List<Expression> addresses) { | ||||||||||||||||||||||||||||
| super(source, CollectionUtils.combine(singletonList(field), addresses)); | ||||||||||||||||||||||||||||
| this.field = field; | ||||||||||||||||||||||||||||
| this.addresses = addresses; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||
| protected TypeResolution resolveType() { | ||||||||||||||||||||||||||||
| if (!childrenResolved()) { | ||||||||||||||||||||||||||||
| return new TypeResolution("Unresolved children"); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| TypeResolution resolution = isIPAndExact(field, sourceText(), Expressions.ParamOrdinal.FIRST); | ||||||||||||||||||||||||||||
| if (resolution.unresolved()) { | ||||||||||||||||||||||||||||
| return resolution; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| for (Expression addr: addresses) { | ||||||||||||||||||||||||||||
| // Currently we have limited enum for ordinal numbers | ||||||||||||||||||||||||||||
| // So just using default here for error messaging | ||||||||||||||||||||||||||||
| resolution = isStringAndExact(addr, sourceText(), ParamOrdinal.DEFAULT); | ||||||||||||||||||||||||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current enum for error messages doesn't work great for variadic type of function. Open to suggestions.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a method here in my wildcard PR: elasticsearch/x-pack/plugin/ql/src/main/java/org/elasticsearch/xpack/ql/expression/Expressions.java Lines 36 to 44 in d482c47
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, should these fields also be Lines 80 to 83 in d482c47
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool! Will update after your PR merges.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For how to handle functions that deal with a variable list of parameters, I suggest having a look at
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Relying on the same def builder here that was merged with |
||||||||||||||||||||||||||||
| if (resolution.unresolved()) { | ||||||||||||||||||||||||||||
| return resolution; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| return resolution; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||
| public boolean foldable() { | ||||||||||||||||||||||||||||
| return super.foldable() && field.foldable() && asFunction().foldable(); | ||||||||||||||||||||||||||||
rw-access marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||
| public Object fold() { | ||||||||||||||||||||||||||||
| return asFunction().fold(); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||
| protected NodeInfo<? extends Expression> info() { | ||||||||||||||||||||||||||||
| return NodeInfo.create(this, CIDRMatch::new, field, addresses); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||
| public ScriptTemplate asScript() { | ||||||||||||||||||||||||||||
| throw new UnsupportedOperationException(); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||
| public DataType dataType() { | ||||||||||||||||||||||||||||
| return DataTypes.BOOLEAN; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||
| public Expression replaceChildren(List<Expression> newChildren) { | ||||||||||||||||||||||||||||
| if (newChildren.size() < 2) { | ||||||||||||||||||||||||||||
| throw new IllegalArgumentException("expected at least [2] children but received [" + newChildren.size() + "]"); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| return new CIDRMatch(source(), newChildren.get(0), newChildren.subList(1, newChildren.size())); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| public ScalarFunction asFunction() { | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| ScalarFunction func = null; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| for (Expression address: addresses) { | ||||||||||||||||||||||||||||
| final Equals eq = new Equals(source(), field, address); | ||||||||||||||||||||||||||||
| func = (func == null) ? eq : new Or(source(), func, eq); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| return func; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed mapping to IP type, this creating the index with mapping.