Browse Source

Fix indices resolver for datemath with colon (#92973)

When resolving concrete indices from expressions, we check that
`ignore_unavailable` is `true` if the expression contains remote names.
The issue is that remote names are recognized when the expression
contains a colon `:`, and that some datemaths can also contain a colon.

The fix here is to run the `ignore_unavailable` check after the
datemath has been evaluated.

Fixes: #92892
Albert Zaharovits 2 years ago
parent
commit
9955b82fbd

+ 5 - 0
docs/changelog/92973.yaml

@@ -0,0 +1,5 @@
+pr: 92973
+summary: Fix indices resolver for datemath with colon
+area: Infra/Core
+type: bug
+issues: []

+ 12 - 12
server/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java

@@ -334,7 +334,6 @@ public class IndexNameExpressionResolver {
     }
 
     Index[] concreteIndices(Context context, String... indexExpressions) {
-        ensureRemoteIndicesRequireIgnoreUnavailable(context.getOptions(), indexExpressions);
         final Collection<String> expressions = resolveExpressions(context, indexExpressions);
 
         final Set<Index> concreteIndicesResult = Sets.newLinkedHashSetWithExpectedSize(expressions.size());
@@ -439,17 +438,6 @@ public class IndexNameExpressionResolver {
         }
     }
 
-    private void ensureRemoteIndicesRequireIgnoreUnavailable(IndicesOptions options, String... indexExpressions) {
-        if (options.ignoreUnavailable() == false && indexExpressions != null) {
-            List<String> crossClusterIndices = Arrays.stream(indexExpressions).filter(index -> index.contains(":")).toList();
-            if (crossClusterIndices.size() > 0) {
-                throw new IllegalArgumentException(
-                    "Cross-cluster calls are not supported in this context but remote indices were requested: " + crossClusterIndices
-                );
-            }
-        }
-    }
-
     private static IndexNotFoundException notFoundException(String... indexExpressions) {
         final IndexNotFoundException infe;
         if (indexExpressions == null
@@ -1523,6 +1511,7 @@ public class IndexNameExpressionResolver {
          * Only explicit resource names are considered for filtering. Wildcard and exclusion expressions are kept in.
          */
         public static List<String> filterUnavailable(Context context, List<String> expressions) {
+            ensureRemoteIndicesRequireIgnoreUnavailable(context.getOptions(), expressions);
             List<String> result = new ArrayList<>(expressions.size());
             for (ExpressionList.Expression expression : new ExpressionList(context, expressions)) {
                 validateAliasOrIndex(expression);
@@ -1582,6 +1571,17 @@ public class IndexNameExpressionResolver {
                 throw new InvalidIndexNameException(expression.expression(), "must not start with '_'.");
             }
         }
+
+        private static void ensureRemoteIndicesRequireIgnoreUnavailable(IndicesOptions options, List<String> indexExpressions) {
+            if (options.ignoreUnavailable() == false) {
+                List<String> crossClusterIndices = indexExpressions.stream().filter(index -> index.contains(":")).toList();
+                if (crossClusterIndices.size() > 0) {
+                    throw new IllegalArgumentException(
+                        "Cross-cluster calls are not supported in this context but remote indices were requested: " + crossClusterIndices
+                    );
+                }
+            }
+        }
     }
 
     /**

+ 6 - 0
server/src/test/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolverTests.java

@@ -3095,6 +3095,12 @@ public class IndexNameExpressionResolverTests extends ESTestCase {
                 "Cross-cluster calls are not supported in this context but remote indices were requested: [cluster:index]",
                 iae.getMessage()
             );
+            // but datemath with colon doesn't trip cross-cluster check
+            IndexNotFoundException e = expectThrows(
+                IndexNotFoundException.class,
+                () -> indexNameExpressionResolver.concreteIndexNames(context, "<datemath-{2001-01-01-13||+1h/h{yyyy-MM-dd-HH|-07:00}}>")
+            );
+            assertThat(e.getMessage(), containsString("no such index [datemath-2001-01-01-14"));
         }
         {
             IndicesOptions options = IndicesOptions.fromOptions(true, true, randomBoolean(), randomBoolean(), randomBoolean());