Allocation: add support for filtering by transport IP address
Allocation filtering by IP only works today using the node host address. But in some cases, you might want to filter using the publish address which could be different.
This commit is contained in:
parent
30ca6d3970
commit
35049a05c3
|
@ -19,9 +19,12 @@
|
|||
|
||||
package org.elasticsearch.cluster.node;
|
||||
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.network.NetworkAddress;
|
||||
import org.elasticsearch.common.regex.Regex;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -64,21 +67,72 @@ public class DiscoveryNodeFilters {
|
|||
this.filters = filters;
|
||||
}
|
||||
|
||||
private boolean matchByIP(String[] values, @Nullable String hostIp, @Nullable String publishIp) {
|
||||
for (String value : values) {
|
||||
boolean matchIp = Regex.simpleMatch(value, hostIp) || Regex.simpleMatch(value, publishIp);
|
||||
if (matchIp) {
|
||||
return matchIp;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean match(DiscoveryNode node) {
|
||||
for (Map.Entry<String, String[]> entry : filters.entrySet()) {
|
||||
String attr = entry.getKey();
|
||||
String[] values = entry.getValue();
|
||||
if ("_ip".equals(attr)) {
|
||||
for (String value : values) {
|
||||
if (Regex.simpleMatch(value, node.getHostAddress())) {
|
||||
if (opType == OpType.OR) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (opType == OpType.AND) {
|
||||
return false;
|
||||
}
|
||||
// We check both the host_ip or the publish_ip
|
||||
String publishAddress = null;
|
||||
if (node.address() instanceof InetSocketTransportAddress) {
|
||||
publishAddress = NetworkAddress.format(((InetSocketTransportAddress) node.address()).address().getAddress());
|
||||
}
|
||||
|
||||
boolean match = matchByIP(values, node.getHostAddress(), publishAddress);
|
||||
|
||||
if (opType == OpType.AND) {
|
||||
if (match) {
|
||||
// If we match, we can check to the next filter
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (match && opType == OpType.OR) {
|
||||
return true;
|
||||
}
|
||||
} else if ("_host_ip".equals(attr)) {
|
||||
// We check explicitly only the host_ip
|
||||
boolean match = matchByIP(values, node.getHostAddress(), null);
|
||||
if (opType == OpType.AND) {
|
||||
if (match) {
|
||||
// If we match, we can check to the next filter
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (match && opType == OpType.OR) {
|
||||
return true;
|
||||
}
|
||||
} else if ("_publish_ip".equals(attr)) {
|
||||
// We check explicitly only the publish_ip
|
||||
String address = null;
|
||||
if (node.address() instanceof InetSocketTransportAddress) {
|
||||
address = NetworkAddress.format(((InetSocketTransportAddress) node.address()).address().getAddress());
|
||||
}
|
||||
|
||||
boolean match = matchByIP(values, address, null);
|
||||
if (opType == OpType.AND) {
|
||||
if (match) {
|
||||
// If we match, we can check to the next filter
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (match && opType == OpType.OR) {
|
||||
return true;
|
||||
}
|
||||
} else if ("_host".equals(attr)) {
|
||||
for (String value : values) {
|
||||
|
@ -171,7 +225,7 @@ public class DiscoveryNodeFilters {
|
|||
for (String value : values) {
|
||||
sb.append(value);
|
||||
if (valueCount > 1) {
|
||||
sb.append(" " + opType.toString() + " ");
|
||||
sb.append(" ").append(opType.toString()).append(" ");
|
||||
}
|
||||
valueCount--;
|
||||
}
|
||||
|
|
|
@ -23,18 +23,38 @@ import com.google.common.collect.ImmutableMap;
|
|||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.transport.DummyTransportAddress;
|
||||
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.cluster.node.DiscoveryNodeFilters.OpType.AND;
|
||||
import static org.elasticsearch.cluster.node.DiscoveryNodeFilters.OpType.OR;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class DiscoveryNodeFiltersTests extends ESTestCase {
|
||||
|
||||
private static InetSocketTransportAddress localAddress;
|
||||
|
||||
@BeforeClass
|
||||
public static void createLocalAddress() throws UnknownHostException {
|
||||
localAddress = new InetSocketTransportAddress(InetAddress.getByName("192.1.1.54"), 9999);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void releaseLocalAddress() {
|
||||
localAddress = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nameMatch() {
|
||||
Settings settings = Settings.settingsBuilder()
|
||||
|
@ -65,10 +85,10 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
|
|||
|
||||
@Test
|
||||
public void idOrNameMatch() {
|
||||
Settings settings = Settings.settingsBuilder()
|
||||
Settings settings = shuffleSettings(Settings.settingsBuilder()
|
||||
.put("xxx._id", "id1,blah")
|
||||
.put("xxx.name", "blah,name2")
|
||||
.build();
|
||||
.build());
|
||||
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
|
||||
|
||||
DiscoveryNode node = new DiscoveryNode("name1", "id1", DummyTransportAddress.INSTANCE, ImmutableMap.<String, String>of(), Version.CURRENT);
|
||||
|
@ -83,22 +103,22 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
|
|||
|
||||
@Test
|
||||
public void tagAndGroupMatch() {
|
||||
Settings settings = Settings.settingsBuilder()
|
||||
Settings settings = shuffleSettings(Settings.settingsBuilder()
|
||||
.put("xxx.tag", "A")
|
||||
.put("xxx.group", "B")
|
||||
.build();
|
||||
.build());
|
||||
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(AND, "xxx.", settings);
|
||||
|
||||
DiscoveryNode node = new DiscoveryNode("name1", "id1", DummyTransportAddress.INSTANCE,
|
||||
ImmutableMap.<String, String>of("tag", "A", "group", "B"), Version.CURRENT);
|
||||
ImmutableMap.of("tag", "A", "group", "B"), Version.CURRENT);
|
||||
assertThat(filters.match(node), equalTo(true));
|
||||
|
||||
node = new DiscoveryNode("name2", "id2", DummyTransportAddress.INSTANCE,
|
||||
ImmutableMap.<String, String>of("tag", "A", "group", "B", "name", "X"), Version.CURRENT);
|
||||
ImmutableMap.of("tag", "A", "group", "B", "name", "X"), Version.CURRENT);
|
||||
assertThat(filters.match(node), equalTo(true));
|
||||
|
||||
node = new DiscoveryNode("name3", "id3", DummyTransportAddress.INSTANCE,
|
||||
ImmutableMap.<String, String>of("tag", "A", "group", "F", "name", "X"), Version.CURRENT);
|
||||
ImmutableMap.of("tag", "A", "group", "F", "name", "X"), Version.CURRENT);
|
||||
assertThat(filters.match(node), equalTo(false));
|
||||
|
||||
node = new DiscoveryNode("name4", "id4", DummyTransportAddress.INSTANCE, ImmutableMap.<String, String>of(), Version.CURRENT);
|
||||
|
@ -115,4 +135,124 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
|
|||
DiscoveryNode node = new DiscoveryNode("name1", "id1", DummyTransportAddress.INSTANCE, ImmutableMap.<String, String>of(), Version.CURRENT);
|
||||
assertThat(filters.match(node), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ipBindFilteringMatchingAnd() {
|
||||
Settings settings = shuffleSettings(Settings.settingsBuilder()
|
||||
.put("xxx.tag", "A")
|
||||
.put("xxx." + randomFrom("_ip", "_host_ip", "_publish_ip"), "192.1.1.54")
|
||||
.build());
|
||||
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(AND, "xxx.", settings);
|
||||
|
||||
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, ImmutableMap.of("tag", "A"), null);
|
||||
assertThat(filters.match(node), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ipBindFilteringNotMatching() {
|
||||
Settings settings = shuffleSettings(Settings.settingsBuilder()
|
||||
.put("xxx.tag", "B")
|
||||
.put("xxx." + randomFrom("_ip", "_host_ip", "_publish_ip"), "192.1.1.54")
|
||||
.build());
|
||||
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(AND, "xxx.", settings);
|
||||
|
||||
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, ImmutableMap.of("tag", "A"), null);
|
||||
assertThat(filters.match(node), equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ipBindFilteringNotMatchingAnd() {
|
||||
Settings settings = shuffleSettings(Settings.settingsBuilder()
|
||||
.put("xxx.tag", "A")
|
||||
.put("xxx." + randomFrom("_ip", "_host_ip", "_publish_ip"), "8.8.8.8")
|
||||
.build());
|
||||
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(AND, "xxx.", settings);
|
||||
|
||||
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, ImmutableMap.of("tag", "A"), null);
|
||||
assertThat(filters.match(node), equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ipBindFilteringMatchingOr() {
|
||||
Settings settings = shuffleSettings(Settings.settingsBuilder()
|
||||
.put("xxx." + randomFrom("_ip", "_host_ip", "_publish_ip"), "192.1.1.54")
|
||||
.put("xxx.tag", "A")
|
||||
.build());
|
||||
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
|
||||
|
||||
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, ImmutableMap.of("tag", "A"), null);
|
||||
assertThat(filters.match(node), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ipBindFilteringNotMatchingOr() {
|
||||
Settings settings = shuffleSettings(Settings.settingsBuilder()
|
||||
.put("xxx.tag", "A")
|
||||
.put("xxx." + randomFrom("_ip", "_host_ip", "_publish_ip"), "8.8.8.8")
|
||||
.build());
|
||||
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
|
||||
|
||||
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, ImmutableMap.of("tag", "A"), null);
|
||||
assertThat(filters.match(node), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ipPublishFilteringMatchingAnd() {
|
||||
Settings settings = shuffleSettings(Settings.settingsBuilder()
|
||||
.put("xxx.tag", "A")
|
||||
.put("xxx._publish_ip", "192.1.1.54")
|
||||
.build());
|
||||
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(AND, "xxx.", settings);
|
||||
|
||||
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, ImmutableMap.of("tag", "A"), null);
|
||||
assertThat(filters.match(node), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ipPublishFilteringNotMatchingAnd() {
|
||||
Settings settings = shuffleSettings(Settings.settingsBuilder()
|
||||
.put("xxx.tag", "A")
|
||||
.put("xxx._publish_ip", "8.8.8.8")
|
||||
.build());
|
||||
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(AND, "xxx.", settings);
|
||||
|
||||
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, ImmutableMap.of("tag", "A"), null);
|
||||
assertThat(filters.match(node), equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ipPublishFilteringMatchingOr() {
|
||||
Settings settings = shuffleSettings(Settings.settingsBuilder()
|
||||
.put("xxx._publish_ip", "192.1.1.54")
|
||||
.put("xxx.tag", "A")
|
||||
.build());
|
||||
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
|
||||
|
||||
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, ImmutableMap.of("tag", "A"), null);
|
||||
assertThat(filters.match(node), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ipPublishFilteringNotMatchingOr() {
|
||||
Settings settings = shuffleSettings(Settings.settingsBuilder()
|
||||
.put("xxx.tag", "A")
|
||||
.put("xxx._publish_ip", "8.8.8.8")
|
||||
.build());
|
||||
DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
|
||||
|
||||
DiscoveryNode node = new DiscoveryNode("", "", "", "192.1.1.54", localAddress, ImmutableMap.of("tag", "A"), null);
|
||||
assertThat(filters.match(node), equalTo(true));
|
||||
}
|
||||
|
||||
private Settings shuffleSettings(Settings source) {
|
||||
Settings.Builder settings = Settings.settingsBuilder();
|
||||
List<String> keys = new ArrayList(source.getAsMap().keySet());
|
||||
Collections.shuffle(keys, getRandom());
|
||||
for (String o : keys) {
|
||||
settings.put(o, source.getAsMap().get(o));
|
||||
}
|
||||
return settings.build();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -81,9 +81,11 @@ one set of nodes to another:
|
|||
These special attributes are also supported:
|
||||
|
||||
[horizontal]
|
||||
`_name`:: Match nodes by node name
|
||||
`_ip`:: Match nodes by IP address (the IP address associated with the hostname)
|
||||
`_host`:: Match nodes by hostname
|
||||
`_name`:: Match nodes by node name
|
||||
`_host_ip`:: Match nodes by host IP address (IP associated with hostname)
|
||||
`_publish_ip`:: Match nodes by publish IP address
|
||||
`_ip`:: Match either `_host_ip` or `_publish_ip`
|
||||
`_host`:: Match nodes by hostname
|
||||
|
||||
All attribute values can be specified with wildcards, eg:
|
||||
|
||||
|
|
Loading…
Reference in New Issue