Skip to content

Commit 329d596

Browse files
authored
Require System Index Descriptors to allow a specific suffix (#78355)
Previously, the leading `.` at the start of system and associated index descriptor patterns was not properly replaced before being compiled as a regular expression, leading to any single-character prefix matching. This commit fixes the issue and adds tests to catch it.
1 parent f68aef6 commit 329d596

File tree

24 files changed

+176
-56
lines changed

24 files changed

+176
-56
lines changed

modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/GeoIpDownloader.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public class GeoIpDownloader extends AllocatedPersistentTask {
6464

6565
public static final String GEOIP_DOWNLOADER = "geoip-downloader";
6666
static final String DATABASES_INDEX = ".geoip_databases";
67+
static final String DATABASES_INDEX_PATTERN = DATABASES_INDEX + "*";
6768
static final int MAX_CHUNK_SIZE = 1024 * 1024;
6869

6970
private final Client client;

modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpPlugin.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import static org.elasticsearch.index.mapper.MapperService.SINGLE_MAPPING_NAME;
6767
import static org.elasticsearch.ingest.IngestService.INGEST_ORIGIN;
6868
import static org.elasticsearch.ingest.geoip.GeoIpDownloader.DATABASES_INDEX;
69+
import static org.elasticsearch.ingest.geoip.GeoIpDownloader.DATABASES_INDEX_PATTERN;
6970
import static org.elasticsearch.ingest.geoip.GeoIpDownloader.GEOIP_DOWNLOADER;
7071

7172
public class IngestGeoIpPlugin extends Plugin implements IngestPlugin, SystemIndexPlugin, Closeable, PersistentTaskPlugin, ActionPlugin {
@@ -160,7 +161,7 @@ public List<NamedWriteableRegistry.Entry> getNamedWriteables() {
160161
@Override
161162
public Collection<SystemIndexDescriptor> getSystemIndexDescriptors(Settings settings) {
162163
SystemIndexDescriptor geoipDatabasesIndex = SystemIndexDescriptor.builder()
163-
.setIndexPattern(DATABASES_INDEX)
164+
.setIndexPattern(DATABASES_INDEX_PATTERN)
164165
.setDescription("GeoIP databases")
165166
.setMappings(mappings())
166167
.setSettings(Settings.builder()

modules/kibana/src/main/java/org/elasticsearch/kibana/KibanaPlugin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ public class KibanaPlugin extends Plugin implements SystemIndexPlugin {
3737
.build();
3838

3939
public static final SystemIndexDescriptor APM_AGENT_CONFIG_INDEX_DESCRIPTOR = SystemIndexDescriptor.builder()
40-
.setIndexPattern(".apm-agent-configuration")
40+
.setIndexPattern(".apm-agent-configuration*")
4141
.setDescription("system index for APM agent configuration")
4242
.setType(Type.EXTERNAL_UNMANAGED)
4343
.setAllowedElasticProductOrigins(KIBANA_PRODUCT_ORIGIN)
4444
.build();
4545

4646
public static final SystemIndexDescriptor APM_CUSTOM_LINK_INDEX_DESCRIPTOR = SystemIndexDescriptor.builder()
47-
.setIndexPattern(".apm-custom-link")
47+
.setIndexPattern(".apm-custom-link*")
4848
.setDescription("system index for APM custom links")
4949
.setType(Type.EXTERNAL_UNMANAGED)
5050
.setAllowedElasticProductOrigins(KIBANA_PRODUCT_ORIGIN)

modules/kibana/src/test/java/org/elasticsearch/kibana/KibanaPluginTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public void testKibanaIndexNames() {
2424
.stream()
2525
.map(SystemIndexDescriptor::getIndexPattern)
2626
.collect(Collectors.toUnmodifiableList()),
27-
contains(".kibana_*", ".reporting-*", ".apm-agent-configuration", ".apm-custom-link")
27+
contains(".kibana_*", ".reporting-*", ".apm-agent-configuration*", ".apm-custom-link*")
2828
);
2929
}
3030
}

server/src/internalClusterTest/java/org/elasticsearch/cluster/ClusterInfoServiceIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public List<ActionFilter> getActionFilters() {
8484

8585
@Override
8686
public Collection<SystemIndexDescriptor> getSystemIndexDescriptors(Settings settings) {
87-
return List.of(new SystemIndexDescriptor(TEST_SYSTEM_INDEX_NAME, "Test system index"));
87+
return List.of(new SystemIndexDescriptor(TEST_SYSTEM_INDEX_NAME + "*", "Test system index"));
8888
}
8989

9090
@Override

server/src/internalClusterTest/java/org/elasticsearch/snapshots/SystemIndicesSnapshotIT.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -960,7 +960,7 @@ public static class AnotherSystemIndexTestPlugin extends Plugin implements Syste
960960

961961
@Override
962962
public Collection<SystemIndexDescriptor> getSystemIndexDescriptors(Settings settings) {
963-
return Collections.singletonList(new SystemIndexDescriptor(SYSTEM_INDEX_NAME, "System indices for tests"));
963+
return Collections.singletonList(new SystemIndexDescriptor(SYSTEM_INDEX_NAME + "*", "System indices for tests"));
964964
}
965965

966966
@Override
@@ -981,7 +981,7 @@ public static class AssociatedIndicesTestPlugin extends Plugin implements System
981981

982982
@Override
983983
public Collection<SystemIndexDescriptor> getSystemIndexDescriptors(Settings settings) {
984-
return Collections.singletonList(new SystemIndexDescriptor(SYSTEM_INDEX_NAME, "System & associated indices for tests"));
984+
return Collections.singletonList(new SystemIndexDescriptor(SYSTEM_INDEX_NAME + "*", "System & associated indices for tests"));
985985
}
986986

987987
@Override

server/src/main/java/org/elasticsearch/indices/SystemIndexDescriptor.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@
4040
* creating the system index, upgrading its mappings, and creating an alias.
4141
*/
4242
public class SystemIndexDescriptor implements IndexPatternMatcher, Comparable<SystemIndexDescriptor> {
43-
/** A pattern, either with a wildcard or simple regex. Indices that match one of these patterns are considered system indices. */
43+
/**
44+
* A pattern, either with a wildcard or simple regex. Indices that match one of these patterns are considered system indices.
45+
* Note that this pattern must not overlap with any other {@link SystemIndexDescriptor}s and must allow an alphanumeric suffix
46+
* (see {@link SystemIndices#UPGRADED_INDEX_SUFFIX} for the specific suffix that's checked) to ensure that there's a name within the
47+
* pattern we can use to create a new index when upgrading.
48+
* */
4449
private final String indexPattern;
4550

4651
/**
@@ -107,7 +112,9 @@ public class SystemIndexDescriptor implements IndexPatternMatcher, Comparable<Sy
107112
/**
108113
* Creates a descriptor for system indices matching the supplied pattern. These indices will not be managed
109114
* by Elasticsearch internally.
110-
* @param indexPattern The pattern of index names that this descriptor will be used for. Must start with a '.' character.
115+
* @param indexPattern The pattern of index names that this descriptor will be used for. Must start with a '.' character, must not
116+
* overlap with any other descriptor patterns, and must allow a suffix (see note on
117+
* {@link SystemIndexDescriptor#indexPattern} for details).
111118
* @param description The name of the plugin responsible for this system index.
112119
*/
113120
public SystemIndexDescriptor(String indexPattern, String description) {
@@ -118,7 +125,9 @@ public SystemIndexDescriptor(String indexPattern, String description) {
118125
/**
119126
* Creates a descriptor for system indices matching the supplied pattern. These indices will not be managed
120127
* by Elasticsearch internally.
121-
* @param indexPattern The pattern of index names that this descriptor will be used for. Must start with a '.' character.
128+
* @param indexPattern The pattern of index names that this descriptor will be used for. Must start with a '.' character, must not
129+
* overlap with any other descriptor patterns, and must allow a suffix (see note on
130+
* {@link SystemIndexDescriptor#indexPattern} for details).
122131
* @param description The name of the plugin responsible for this system index.
123132
* @param type The {@link Type} of system index
124133
* @param allowedElasticProductOrigins A list of allowed origin values that should be allowed access in the case of external system
@@ -133,7 +142,9 @@ public SystemIndexDescriptor(String indexPattern, String description, Type type,
133142
* Creates a descriptor for system indices matching the supplied pattern. These indices will be managed
134143
* by Elasticsearch internally if mappings or settings are provided.
135144
*
136-
* @param indexPattern The pattern of index names that this descriptor will be used for. Must start with a '.' character.
145+
* @param indexPattern The pattern of index names that this descriptor will be used for. Must start with a '.' character, must not
146+
* overlap with any other descriptor patterns, and must allow a suffix (see note on
147+
* {@link SystemIndexDescriptor#indexPattern} for details).
137148
* @param primaryIndex The primary index name of this descriptor. Used when creating the system index for the first time.
138149
* @param description The name of the plugin responsible for this system index.
139150
* @param mappings The mappings to apply to this index when auto-creating, if appropriate
@@ -314,7 +325,9 @@ public SystemIndexDescriptor(String indexPattern, String description, Type type,
314325

315326

316327
/**
317-
* @return The pattern of index names that this descriptor will be used for.
328+
* @return The pattern of index names that this descriptor will be used for. Must start with a '.' character, must not
329+
* overlap with any other descriptor patterns, and must allow a suffix (see note on
330+
* {@link SystemIndexDescriptor#indexPattern} for details).
318331
*/
319332
@Override
320333
public String getIndexPattern() {

server/src/main/java/org/elasticsearch/indices/SystemIndices.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
package org.elasticsearch.indices;
1010

11+
import org.apache.logging.log4j.message.ParameterizedMessage;
1112
import org.apache.lucene.util.automaton.Automata;
1213
import org.apache.lucene.util.automaton.Automaton;
1314
import org.apache.lucene.util.automaton.CharacterRunAutomaton;
@@ -58,6 +59,7 @@
5859
public class SystemIndices {
5960
public static final String SYSTEM_INDEX_ACCESS_CONTROL_HEADER_KEY = "_system_index_access_allowed";
6061
public static final String EXTERNAL_SYSTEM_INDEX_ACCESS_CONTROL_HEADER_KEY = "_external_system_index_access_origin";
62+
public static final String UPGRADED_INDEX_SUFFIX = "-reindexed-for-8";
6163

6264
private static final Automaton EMPTY = Automata.makeEmpty();
6365

@@ -83,6 +85,7 @@ TASKS_FEATURE_NAME, new Feature(TASKS_FEATURE_NAME, "Manages task results", List
8385
public SystemIndices(Map<String, Feature> pluginAndModulesDescriptors) {
8486
featureDescriptors = buildSystemIndexDescriptorMap(pluginAndModulesDescriptors);
8587
checkForOverlappingPatterns(featureDescriptors);
88+
ensurePatternsAllowSuffix(featureDescriptors);
8689
checkForDuplicateAliases(this.getSystemIndexDescriptors());
8790
Automaton systemIndexAutomata = buildIndexAutomaton(featureDescriptors);
8891
this.systemIndexRunAutomaton = new CharacterRunAutomaton(systemIndexAutomata);
@@ -99,6 +102,35 @@ public SystemIndices(Map<String, Feature> pluginAndModulesDescriptors) {
99102
this.systemNameRunAutomaton = new CharacterRunAutomaton(systemNameAutomaton);
100103
}
101104

105+
static void ensurePatternsAllowSuffix(Map<String, Feature> features) {
106+
String suffixPattern = "*" + UPGRADED_INDEX_SUFFIX;
107+
final List<String> descriptorsWithNoRoomForSuffix = features.entrySet()
108+
.stream()
109+
.flatMap(
110+
feature -> feature.getValue().getIndexDescriptors()
111+
.stream()
112+
// The below filter & map are inside the enclosing flapMap so we have access to both the feature and the descriptor
113+
.filter(descriptor -> overlaps(descriptor.getIndexPattern(), suffixPattern) == false)
114+
.map(
115+
descriptor -> new ParameterizedMessage(
116+
"pattern [{}] from feature [{}]",
117+
descriptor.getIndexPattern(),
118+
feature.getKey()
119+
).getFormattedMessage()
120+
)
121+
)
122+
.collect(Collectors.toList());
123+
if (descriptorsWithNoRoomForSuffix.isEmpty() == false) {
124+
throw new IllegalStateException(
125+
new ParameterizedMessage(
126+
"the following system index patterns do not allow suffix [{}] required to allow upgrades: [{}]",
127+
UPGRADED_INDEX_SUFFIX,
128+
descriptorsWithNoRoomForSuffix
129+
).getFormattedMessage()
130+
);
131+
}
132+
}
133+
102134
private static void checkForDuplicateAliases(Collection<SystemIndexDescriptor> descriptors) {
103135
final Map<String, Integer> aliasCounts = new HashMap<>();
104136

server/src/test/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesActionTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ public void testDeprecationWarningEmittedWhenRequestingNonExistingAliasInSystemP
176176
SystemIndices systemIndices = new SystemIndices(Collections.singletonMap(
177177
this.getTestName(),
178178
new SystemIndices.Feature(this.getTestName(), "test feature",
179-
Collections.singletonList(new SystemIndexDescriptor(".y", "an index that doesn't exist")))));
179+
Collections.singletonList(new SystemIndexDescriptor(".y*", "an index that doesn't exist")))));
180180

181181
GetAliasesRequest request = new GetAliasesRequest(".y");
182182
ImmutableOpenMap<String, List<AliasMetadata>> aliases = ImmutableOpenMap.<String, List<AliasMetadata>>builder()
@@ -229,7 +229,7 @@ public void testNetNewSystemIndicesDontErrorWhenNotRequested() {
229229
String[] concreteIndices;
230230

231231
SystemIndexDescriptor netNewDescriptor = SystemIndexDescriptor.builder()
232-
.setIndexPattern(".b")
232+
.setIndexPattern(".b*")
233233
.setAliasName(".y")
234234
.setPrimaryIndex(".b")
235235
.setDescription(this.getTestName())

server/src/test/java/org/elasticsearch/action/admin/indices/settings/put/TransportUpdateSettingsActionTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public class TransportUpdateSettingsActionTests extends ESTestCase {
5858
Map.of("test-feature", new SystemIndices.Feature(
5959
"test-feature",
6060
"a test feature",
61-
List.of(new SystemIndexDescriptor(SYSTEM_INDEX_NAME, "test"))
61+
List.of(new SystemIndexDescriptor(SYSTEM_INDEX_NAME + "*", "test"))
6262
))
6363
);
6464

0 commit comments

Comments
 (0)