Skip to content

Commit 2ce69fb

Browse files
authored
[es-query] Add indexPatternToCcs helper (#233564)
Adds `indexPatternToCcs` helper that returns local + CCS variants of specified index patterns.
1 parent 576def4 commit 2ce69fb

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

src/platform/packages/shared/kbn-es-query/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ export {
116116
BooleanRelation,
117117
} from './src/filters';
118118

119+
export { indexPatternToCcs } from './src/indices';
120+
119121
export {
120122
KQLSyntaxError,
121123
fromKueryExpression,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
export { indexPatternToCcs } from './index_pattern_to_ccs';
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
import { indexPatternToCcs } from './index_pattern_to_ccs';
11+
12+
describe('indexPatternToCcs', () => {
13+
it('expands a simple local pattern', () => {
14+
const result = indexPatternToCcs('logs-*');
15+
expect(result).toEqual(['logs-*', '*:logs-*']);
16+
});
17+
18+
it('returns remote-cluster pattern untouched', () => {
19+
const result = indexPatternToCcs('prod:logs-*');
20+
expect(result).toEqual(['prod:logs-*']);
21+
});
22+
23+
it('returns wildcard-cluster pattern untouched', () => {
24+
const result = indexPatternToCcs('*:metrics-*');
25+
expect(result).toEqual(['*:metrics-*']);
26+
});
27+
28+
it('expands local failure-store pattern', () => {
29+
const result = indexPatternToCcs('logs-*::failures');
30+
expect(result).toEqual(['logs-*::failures', '*:logs-*::failures']);
31+
});
32+
33+
it('handles array input and deduplication', () => {
34+
const result = indexPatternToCcs(['logs-*', 'prod:metrics-*', '*:logs-*']);
35+
expect(result).toEqual(['logs-*', '*:logs-*', 'prod:metrics-*']);
36+
});
37+
38+
it('splits comma-separated string', () => {
39+
const result = indexPatternToCcs('logs-*, metrics-*');
40+
expect(result).toEqual(['logs-*', '*:logs-*', 'metrics-*', '*:metrics-*']);
41+
});
42+
});
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
import { castArray } from 'lodash';
11+
12+
function isCrossCluster(pattern: string): boolean {
13+
if (pattern.startsWith('*:')) return true; // already wildcard cluster
14+
15+
// simple, cheap heuristic first
16+
if (!pattern.includes(':')) {
17+
return false;
18+
}
19+
20+
// match on single `:`, but exclude `::` which is used for e.g. `::failure`
21+
return /(?<!:):(?!:)/.test(pattern);
22+
}
23+
24+
/**
25+
* Appends cross-cluster search equivalents for each specified index pattern.
26+
* Use this when you want to query both local and cross-cluster indices automatically.
27+
*/
28+
export function indexPatternToCcs(index: string | string[]) {
29+
// split on commas, normalise whitespace, and drop empty indices
30+
const indices = castArray(index)
31+
.flatMap((idx) => idx.split(','))
32+
.map((i) => i.trim())
33+
.filter(Boolean);
34+
35+
const expanded = new Set<string>();
36+
for (const idx of indices) {
37+
expanded.add(idx);
38+
if (!isCrossCluster(idx)) {
39+
expanded.add(`*:${idx}`);
40+
}
41+
}
42+
43+
return Array.from(expanded);
44+
}

0 commit comments

Comments
 (0)