Browse Source

Allow wildcards for shard IP filtering (#26187)

Fixes the broken usage of wildcards for IP-based allocation filtering (introduced by PR #22591), which is documented at https://www.elastic.co/guide/en/elasticsearch/reference/current/shard-allocation-filtering.html

Closes #26184
Yannick Welsch 8 years ago
parent
commit
fe0c68ec8f

+ 2 - 2
core/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeFilters.java

@@ -41,7 +41,7 @@ public class DiscoveryNodeFilters {
     /**
      * Validates the IP addresses in a group of {@link Settings} by looking for the keys
      * "_ip", "_host_ip", and "_publish_ip" and ensuring each of their comma separated values
-     * is a valid IP address.
+     * that has no wildcards is a valid IP address.
      */
     public static final Consumer<Settings> IP_VALIDATOR = (settings) -> {
         Map<String, String> settingsMap = settings.getAsMap();
@@ -52,7 +52,7 @@ public class DiscoveryNodeFilters {
             }
             if ("_ip".equals(propertyKey) || "_host_ip".equals(propertyKey) || "_publish_ip".equals(propertyKey)) {
                 for (String value : Strings.tokenizeToStringArray(entry.getValue(), ",")) {
-                    if (InetAddresses.isInetAddress(value) == false) {
+                    if (Regex.isSimpleMatchPattern(value) == false && InetAddresses.isInetAddress(value) == false) {
                         throw new IllegalArgumentException("invalid IP address [" + value + "] for [" + propertyKey + "]");
                     }
                 }

+ 11 - 0
core/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodeFiltersTests.java

@@ -245,6 +245,17 @@ public class DiscoveryNodeFiltersTests extends ESTestCase {
         assertThat(filters.match(node), equalTo(true));
     }
 
+    public void testIpPublishFilteringMatchingWildcard() {
+        boolean matches = randomBoolean();
+        Settings settings = shuffleSettings(Settings.builder()
+            .put("xxx._publish_ip", matches ? "192.1.*" : "192.2.*")
+            .build());
+        DiscoveryNodeFilters filters = DiscoveryNodeFilters.buildFromSettings(OR, "xxx.", settings);
+
+        DiscoveryNode node = new DiscoveryNode("", "", "", "", "192.1.1.54", localAddress, emptyMap(), emptySet(), null);
+        assertThat(filters.match(node), equalTo(matches));
+    }
+
     public void testCommaSeparatedValuesTrimmed() {
         DiscoveryNode node = new DiscoveryNode("", "", "", "", "192.1.1.54", localAddress, singletonMap("tag", "B"), emptySet(), null);
 

+ 13 - 2
core/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDeciderTests.java

@@ -185,11 +185,22 @@ public class FilterAllocationDeciderTests extends ESAllocationTestCase {
         String ipKey = randomFrom("_ip", "_host_ip", "_publish_ip");
         Setting<Settings> filterSetting = randomFrom(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING,
             IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING, IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING);
+        String invalidIP = randomFrom("192..168.1.1", "192.300.1.1");
         IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> {
             IndexScopedSettings indexScopedSettings = new IndexScopedSettings(Settings.EMPTY, IndexScopedSettings.BUILT_IN_INDEX_SETTINGS);
-            indexScopedSettings.updateDynamicSettings(Settings.builder().put(filterSetting.getKey() + ipKey, "192..168.1.1").build(),
+            indexScopedSettings.updateDynamicSettings(Settings.builder().put(filterSetting.getKey() + ipKey, invalidIP).build(),
                 Settings.builder().put(Settings.EMPTY), Settings.builder(), "test ip validation");
         });
-        assertEquals("invalid IP address [192..168.1.1] for [" + ipKey + "]", e.getMessage());
+        assertEquals("invalid IP address [" + invalidIP + "] for [" + ipKey + "]", e.getMessage());
+    }
+
+    public void testWildcardIPFilter() {
+        String ipKey = randomFrom("_ip", "_host_ip", "_publish_ip");
+        Setting<Settings> filterSetting = randomFrom(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING,
+            IndexMetaData.INDEX_ROUTING_INCLUDE_GROUP_SETTING, IndexMetaData.INDEX_ROUTING_EXCLUDE_GROUP_SETTING);
+        String wildcardIP = randomFrom("192.168.*", "192.*.1.1");
+        IndexScopedSettings indexScopedSettings = new IndexScopedSettings(Settings.EMPTY, IndexScopedSettings.BUILT_IN_INDEX_SETTINGS);
+        indexScopedSettings.updateDynamicSettings(Settings.builder().put(filterSetting.getKey() + ipKey, wildcardIP).build(),
+            Settings.builder().put(Settings.EMPTY), Settings.builder(), "test ip validation");
     }
 }