Skip to content

Commit eb32a9b

Browse files
joegallomasseyke
andauthored
Fix geoip databases index access after system feature migration (elastic#121196) (elastic#121946)
Co-authored-by: Keith Massey <[email protected]>
1 parent b736749 commit eb32a9b

File tree

4 files changed

+114
-4
lines changed

4 files changed

+114
-4
lines changed

docs/changelog/121196.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 121196
2+
summary: Fix geoip databases index access after system feature migration
3+
area: Ingest Node
4+
type: bug
5+
issues: []

modules/ingest-geoip/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/ingest/geoip/FullClusterRestartIT.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,16 @@ public void testGeoIpSystemFeaturesMigration() throws Exception {
119119

120120
// before the upgrade, Kibana should work
121121
assertBusy(() -> testGetStarAsKibana(List.of("my-index-00001"), maybeSecurityIndex));
122+
123+
// as should a normal get *
124+
assertBusy(() -> testGetStar(List.of("my-index-00001"), maybeSecurityIndex));
122125
} else {
123126
// after the upgrade, but before the migration, Kibana should work
124127
assertBusy(() -> testGetStarAsKibana(List.of("my-index-00001"), maybeSecurityIndex));
125128

129+
// as should a normal get *
130+
assertBusy(() -> testGetStar(List.of("my-index-00001"), maybeSecurityIndex));
131+
126132
// migrate the system features and give the cluster a moment to settle
127133
Request migrateSystemFeatures = new Request("POST", "/_migration/system_features");
128134
assertOK(client().performRequest(migrateSystemFeatures));
@@ -132,9 +138,10 @@ public void testGeoIpSystemFeaturesMigration() throws Exception {
132138
assertBusy(() -> testIndexGeoDoc());
133139

134140
// after the migration, Kibana should work
135-
if (useSecurity == false) { // BUT IT DOESN'T if security is enabled
136-
assertBusy(() -> testGetStarAsKibana(List.of("my-index-00001"), maybeSecurityIndexReindexed));
137-
}
141+
assertBusy(() -> testGetStarAsKibana(List.of("my-index-00001"), maybeSecurityIndexReindexed));
142+
143+
// as should a normal get *
144+
assertBusy(() -> testGetStar(List.of("my-index-00001"), maybeSecurityIndexReindexed));
138145

139146
Request disableDownloader = new Request("PUT", "/_cluster/settings");
140147
disableDownloader.setJsonEntity("""
@@ -213,6 +220,23 @@ private void testIndexGeoDoc() throws IOException {
213220
assertEquals("Sweden", doc.evaluate("_source.geo.country_name"));
214221
}
215222

223+
private void testGetStar(List<String> indexNames, @Nullable List<String> additionalIndexNames) throws IOException {
224+
Request getStar = new Request("GET", "*?expand_wildcards=all");
225+
getStar.setOptions(
226+
RequestOptions.DEFAULT.toBuilder().setWarningsHandler(WarningsHandler.PERMISSIVE) // we don't care about warnings, just errors
227+
);
228+
Response response = client().performRequest(getStar);
229+
assertOK(response);
230+
231+
if (additionalIndexNames != null && additionalIndexNames.isEmpty() == false) {
232+
indexNames = new ArrayList<>(indexNames); // recopy into a mutable list
233+
indexNames.addAll(additionalIndexNames);
234+
}
235+
236+
Map<String, Object> map = responseAsMap(response);
237+
assertThat(map.keySet(), is(new HashSet<>(indexNames)));
238+
}
239+
216240
private void testGetStarAsKibana(List<String> indexNames, @Nullable List<String> additionalIndexNames) throws IOException {
217241
Request getStar = new Request("GET", "*?expand_wildcards=all");
218242
getStar.setOptions(

server/src/main/java/org/elasticsearch/cluster/metadata/IndexAbstractionResolver.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ public static boolean isIndexVisible(
168168
final boolean isHidden = indexAbstraction.isHidden();
169169
boolean isVisible = isHidden == false || indicesOptions.expandWildcardsHidden() || isVisibleDueToImplicitHidden(expression, index);
170170
if (indexAbstraction.getType() == IndexAbstraction.Type.ALIAS) {
171+
if (indexAbstraction.isSystem()) {
172+
// check if it is net new
173+
if (resolver.getNetNewSystemIndexPredicate().test(indexAbstraction.getName())) {
174+
return isSystemIndexVisible(resolver, indexAbstraction);
175+
}
176+
}
177+
171178
// it's an alias, ignore expandWildcardsOpen and expandWildcardsClosed.
172179
// complicated to support those options with aliases pointing to multiple indices...
173180
isVisible = isVisible && indicesOptions.ignoreAliases() == false;

server/src/test/java/org/elasticsearch/cluster/metadata/IndexAbstractionResolverTests.java

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,24 @@
1313
import org.elasticsearch.common.settings.Settings;
1414
import org.elasticsearch.common.util.concurrent.ThreadContext;
1515
import org.elasticsearch.core.Tuple;
16+
import org.elasticsearch.index.IndexVersion;
1617
import org.elasticsearch.indices.EmptySystemIndices;
1718
import org.elasticsearch.indices.InvalidIndexNameException;
19+
import org.elasticsearch.indices.SystemIndexDescriptor;
20+
import org.elasticsearch.indices.SystemIndices;
1821
import org.elasticsearch.test.ESTestCase;
22+
import org.elasticsearch.xcontent.XContentBuilder;
1923

24+
import java.io.IOException;
25+
import java.io.UncheckedIOException;
2026
import java.util.List;
2127
import java.util.Set;
2228
import java.util.concurrent.TimeUnit;
2329
import java.util.function.Supplier;
2430

31+
import static org.elasticsearch.index.mapper.MapperService.SINGLE_MAPPING_NAME;
32+
import static org.elasticsearch.indices.SystemIndices.SYSTEM_INDEX_ACCESS_CONTROL_HEADER_KEY;
33+
import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder;
2534
import static org.hamcrest.Matchers.contains;
2635
import static org.hamcrest.Matchers.containsInAnyOrder;
2736
import static org.hamcrest.Matchers.either;
@@ -220,13 +229,78 @@ private boolean isIndexVisible(String index, String selector) {
220229
"*",
221230
selector,
222231
index,
223-
IndicesOptions.strictExpandOpen(),
232+
IndicesOptions.strictExpandHidden(),
224233
metadata,
225234
indexNameExpressionResolver,
226235
true
227236
);
228237
}
229238

239+
public void testIsNetNewSystemIndexVisible() {
240+
final Settings settings = Settings.builder()
241+
.put("index.number_of_replicas", 0)
242+
.put("index.number_of_shards", 1)
243+
.put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current())
244+
.build();
245+
246+
final Settings hiddenSettings = Settings.builder().put(settings).put("index.hidden", true).build();
247+
248+
final IndexMetadata foo = IndexMetadata.builder(".foo").settings(hiddenSettings).system(true).build();
249+
final IndexMetadata barReindexed = IndexMetadata.builder(".bar-reindexed")
250+
.settings(hiddenSettings)
251+
.system(true)
252+
.putAlias(AliasMetadata.builder(".bar").isHidden(true).build())
253+
.build();
254+
final IndexMetadata other = IndexMetadata.builder("other").settings(settings).build();
255+
256+
final SystemIndexDescriptor fooDescriptor = SystemIndexDescriptor.builder()
257+
.setDescription("foo indices")
258+
.setOrigin("foo origin")
259+
.setPrimaryIndex(".foo")
260+
.setIndexPattern(".foo*")
261+
.setSettings(settings)
262+
.setMappings(mappings())
263+
.setNetNew()
264+
.build();
265+
final SystemIndexDescriptor barDescriptor = SystemIndexDescriptor.builder()
266+
.setDescription("bar indices")
267+
.setOrigin("bar origin")
268+
.setPrimaryIndex(".bar")
269+
.setIndexPattern(".bar*")
270+
.setSettings(settings)
271+
.setMappings(mappings())
272+
.setNetNew()
273+
.build();
274+
final SystemIndices systemIndices = new SystemIndices(
275+
List.of(new SystemIndices.Feature("name", "description", List.of(fooDescriptor, barDescriptor)))
276+
);
277+
278+
final ThreadContext threadContext = new ThreadContext(Settings.EMPTY);
279+
threadContext.putHeader(SYSTEM_INDEX_ACCESS_CONTROL_HEADER_KEY, "false");
280+
indexNameExpressionResolver = new IndexNameExpressionResolver(threadContext, systemIndices);
281+
indexAbstractionResolver = new IndexAbstractionResolver(indexNameExpressionResolver);
282+
283+
metadata = Metadata.builder().put(foo, true).put(barReindexed, true).put(other, true).build();
284+
285+
assertThat(isIndexVisible("other", "*"), is(true));
286+
assertThat(isIndexVisible(".foo", "*"), is(false));
287+
assertThat(isIndexVisible(".bar", "*"), is(false));
288+
}
289+
290+
private static XContentBuilder mappings() {
291+
try (XContentBuilder builder = jsonBuilder()) {
292+
return builder.startObject()
293+
.startObject(SINGLE_MAPPING_NAME)
294+
.startObject("_meta")
295+
.field(SystemIndexDescriptor.VERSION_META_KEY, 0)
296+
.endObject()
297+
.endObject()
298+
.endObject();
299+
} catch (IOException e) {
300+
throw new UncheckedIOException(e);
301+
}
302+
}
303+
230304
private List<String> resolveAbstractionsSelectorNotAllowed(List<String> expressions) {
231305
return resolveAbstractions(expressions, IndicesOptions.strictExpandHiddenNoSelectors(), defaultMask);
232306
}

0 commit comments

Comments
 (0)