-
Notifications
You must be signed in to change notification settings - Fork 0
ESQL: Implement network_direction function
#7
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
base: main
Are you sure you want to change the base?
Changes from all commits
9637798
3129e57
13fe69d
07b6c8f
319552e
1fd1e51
08647b2
c4196a2
295931a
584de17
1502b71
737eae0
b80ef49
5e24512
f98b9e0
0e7ba55
e1b1e67
463cd79
d810ecf
af8038c
d788b52
22d301a
095106c
8c400af
925d793
c17a755
dab3921
24d8f30
a766c77
6a34869
18e39e6
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,5 @@ | ||
| pr: 136133 | ||
| summary: Implement `network_direction` function | ||
| area: ES|QL | ||
| type: enhancement | ||
| issues: [] | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -10,47 +10,25 @@ | |||||||||||||||||||||||||||||||||||||||||||||||
| package org.elasticsearch.ingest.common; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| import org.elasticsearch.cluster.metadata.ProjectId; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import org.elasticsearch.common.network.CIDRUtils; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import org.elasticsearch.common.network.InetAddresses; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import org.elasticsearch.common.network.NetworkDirectionUtils; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import org.elasticsearch.ingest.AbstractProcessor; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import org.elasticsearch.ingest.ConfigurationUtils; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import org.elasticsearch.ingest.IngestDocument; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import org.elasticsearch.ingest.Processor; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import org.elasticsearch.script.ScriptService; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import org.elasticsearch.script.TemplateScript; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| import java.net.InetAddress; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.ArrayList; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Arrays; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Map; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| import static org.elasticsearch.ingest.ConfigurationUtils.newConfigurationException; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import static org.elasticsearch.ingest.ConfigurationUtils.readBooleanProperty; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| public class NetworkDirectionProcessor extends AbstractProcessor { | ||||||||||||||||||||||||||||||||||||||||||||||||
| static final byte[] UNDEFINED_IP4 = new byte[] { 0, 0, 0, 0 }; | ||||||||||||||||||||||||||||||||||||||||||||||||
| static final byte[] UNDEFINED_IP6 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | ||||||||||||||||||||||||||||||||||||||||||||||||
| static final byte[] BROADCAST_IP4 = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| public static final String TYPE = "network_direction"; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| public static final String DIRECTION_INTERNAL = "internal"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| public static final String DIRECTION_EXTERNAL = "external"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| public static final String DIRECTION_INBOUND = "inbound"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| public static final String DIRECTION_OUTBOUND = "outbound"; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String LOOPBACK_NAMED_NETWORK = "loopback"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String GLOBAL_UNICAST_NAMED_NETWORK = "global_unicast"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String UNICAST_NAMED_NETWORK = "unicast"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String LINK_LOCAL_UNICAST_NAMED_NETWORK = "link_local_unicast"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String INTERFACE_LOCAL_NAMED_NETWORK = "interface_local_multicast"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String LINK_LOCAL_MULTICAST_NAMED_NETWORK = "link_local_multicast"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String MULTICAST_NAMED_NETWORK = "multicast"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String UNSPECIFIED_NAMED_NETWORK = "unspecified"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String PRIVATE_NAMED_NETWORK = "private"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String PUBLIC_NAMED_NETWORK = "public"; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private final String sourceIpField; | ||||||||||||||||||||||||||||||||||||||||||||||||
| private final String destinationIpField; | ||||||||||||||||||||||||||||||||||||||||||||||||
| private final String targetField; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -140,96 +118,10 @@ private String getDirection(IngestDocument d) throws Exception { | |||||||||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| boolean sourceInternal = isInternal(networks, sourceIpAddrString); | ||||||||||||||||||||||||||||||||||||||||||||||||
| boolean destinationInternal = isInternal(networks, destIpAddrString); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| if (sourceInternal && destinationInternal) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return DIRECTION_INTERNAL; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| if (sourceInternal) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return DIRECTION_OUTBOUND; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| if (destinationInternal) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return DIRECTION_INBOUND; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| return DIRECTION_EXTERNAL; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private static boolean isInternal(List<String> networks, String ip) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| for (String network : networks) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| if (inNetwork(ip, network)) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private static boolean inNetwork(String ip, String network) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| InetAddress address = InetAddresses.forString(ip); | ||||||||||||||||||||||||||||||||||||||||||||||||
| return switch (network) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| case LOOPBACK_NAMED_NETWORK -> isLoopback(address); | ||||||||||||||||||||||||||||||||||||||||||||||||
| case GLOBAL_UNICAST_NAMED_NETWORK, UNICAST_NAMED_NETWORK -> isUnicast(address); | ||||||||||||||||||||||||||||||||||||||||||||||||
| case LINK_LOCAL_UNICAST_NAMED_NETWORK -> isLinkLocalUnicast(address); | ||||||||||||||||||||||||||||||||||||||||||||||||
| case INTERFACE_LOCAL_NAMED_NETWORK -> isInterfaceLocalMulticast(address); | ||||||||||||||||||||||||||||||||||||||||||||||||
| case LINK_LOCAL_MULTICAST_NAMED_NETWORK -> isLinkLocalMulticast(address); | ||||||||||||||||||||||||||||||||||||||||||||||||
| case MULTICAST_NAMED_NETWORK -> isMulticast(address); | ||||||||||||||||||||||||||||||||||||||||||||||||
| case UNSPECIFIED_NAMED_NETWORK -> isUnspecified(address); | ||||||||||||||||||||||||||||||||||||||||||||||||
| case PRIVATE_NAMED_NETWORK -> isPrivate(ip); | ||||||||||||||||||||||||||||||||||||||||||||||||
| case PUBLIC_NAMED_NETWORK -> isPublic(ip); | ||||||||||||||||||||||||||||||||||||||||||||||||
| default -> CIDRUtils.isInRange(ip, network); | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private static boolean isLoopback(InetAddress ip) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return ip.isLoopbackAddress(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private static boolean isUnicast(InetAddress ip) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return Arrays.equals(ip.getAddress(), BROADCAST_IP4) == false | ||||||||||||||||||||||||||||||||||||||||||||||||
| && isUnspecified(ip) == false | ||||||||||||||||||||||||||||||||||||||||||||||||
| && isLoopback(ip) == false | ||||||||||||||||||||||||||||||||||||||||||||||||
| && isMulticast(ip) == false | ||||||||||||||||||||||||||||||||||||||||||||||||
| && isLinkLocalUnicast(ip) == false; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private static boolean isLinkLocalUnicast(InetAddress ip) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return ip.isLinkLocalAddress(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private static boolean isInterfaceLocalMulticast(InetAddress ip) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return ip.isMCNodeLocal(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private static boolean isLinkLocalMulticast(InetAddress ip) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return ip.isMCLinkLocal(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private static boolean isMulticast(InetAddress ip) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return ip.isMulticastAddress(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private static boolean isUnspecified(InetAddress ip) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| var address = ip.getAddress(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| return Arrays.equals(UNDEFINED_IP4, address) || Arrays.equals(UNDEFINED_IP6, address); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private static boolean isPrivate(String ip) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return CIDRUtils.isInRange(ip, "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "fd00::/8"); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private static boolean isPublic(String ip) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return isLocalOrPrivate(ip) == false; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| boolean sourceInternal = NetworkDirectionUtils.isInternal(networks, sourceIpAddrString); | ||||||||||||||||||||||||||||||||||||||||||||||||
| boolean destinationInternal = NetworkDirectionUtils.isInternal(networks, destIpAddrString); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| private static boolean isLocalOrPrivate(String ip) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| var address = InetAddresses.forString(ip); | ||||||||||||||||||||||||||||||||||||||||||||||||
| return isPrivate(ip) | ||||||||||||||||||||||||||||||||||||||||||||||||
| || isLoopback(address) | ||||||||||||||||||||||||||||||||||||||||||||||||
| || isUnspecified(address) | ||||||||||||||||||||||||||||||||||||||||||||||||
| || isLinkLocalUnicast(address) | ||||||||||||||||||||||||||||||||||||||||||||||||
| || isLinkLocalMulticast(address) | ||||||||||||||||||||||||||||||||||||||||||||||||
| || isInterfaceLocalMulticast(address) | ||||||||||||||||||||||||||||||||||||||||||||||||
| || Arrays.equals(address.getAddress(), BROADCAST_IP4); | ||||||||||||||||||||||||||||||||||||||||||||||||
| return NetworkDirectionUtils.getDirection(sourceInternal, destinationInternal); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+121
to
+124
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. Suggestion: Catch and handle potential parsing/validation errors from
Suggested change
Why Change? ⭐The improved code is a small, local change inside the existing getDirection(...) method and uses only symbols already present in the class: the imported NetworkDirectionUtils and the instance field Catching IllegalArgumentException is a conservative choice for handling parsing/validation failures from NetworkDirectionUtils.isInternal (which commonly signals invalid input via IllegalArgumentException). When such an exception occurs, returning null if The code is syntactically valid Java, compiles in-place (no new imports or signatures required), and does not introduce new checked exceptions. Assumptions: NetworkDirectionUtils and the ignoreMissing field exist as shown in the PR and NetworkDirectionUtils.isInternal may throw IllegalArgumentException for invalid inputs. Given these, the change is safe and executable and does not introduce new bugs. |
||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
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.
Suggestion: Quote the
areavalue (which contains a pipe character) to avoid YAML parsing ambiguity and ensure consistent cross-platform parsing. [best practice]Why Change? ⭐
Quoting the 'area' scalar is a harmless, backward-compatible change that prevents any YAML parsers
or tooling from misinterpreting the '|' character. The improved code preserves the exact string value
("ES|QL") while ensuring the YAML remains unambiguous across different parsers and platforms.
The syntax is valid YAML, no new identifiers or methods are referenced, and the document remains
structurally identical aside from the added quotes. Therefore this change is executable and safe.