Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System indices treated as restricted indices #74212

Merged
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
f863e01
System indices treated as restricted indices
jaymode Apr 30, 2021
b0832da
restricted index updates
jaymode Jun 16, 2021
35b739d
Merge remote-tracking branch 'origin/master' into system_indices_rest…
jaymode Jun 17, 2021
92bfa5f
admin role needs restricted index access for now
jaymode Jun 17, 2021
a11ff2f
fix test failures
jaymode Jun 17, 2021
b12116b
fix test
jaymode Jun 17, 2021
74bfe52
Revert "fix test"
jaymode Jun 17, 2021
69d6e6d
remove some of restrictedindicesnames
jaymode Jun 17, 2021
98c7d58
fixes
jaymode Jun 17, 2021
c106902
fix bad version name
jaymode Jun 17, 2021
1bca2a9
unused
jaymode Jun 17, 2021
5ee3b18
fix test cp
jaymode Jun 18, 2021
cd863d1
Merge branch 'master' into system_indices_restricted_indices
jaymode Jun 28, 2021
48f3ec6
Merge branch 'master' into system_indices_restricted_indices
williamrandolph Jul 27, 2021
5c3f54a
Improve automaton build stream
williamrandolph Jul 27, 2021
7aa5ea0
Handle warnings in tests
williamrandolph Jul 27, 2021
00a68c0
Add some javadoc
williamrandolph Jul 29, 2021
80e4be1
Merge branch 'master' into system_indices_restricted_indices
williamrandolph Jul 29, 2021
7c2c04b
DRY by using automaton in constructing a predicate
williamrandolph Jul 29, 2021
28379ba
Refactor to avoid repeating code
williamrandolph Jul 29, 2021
7c7e992
Rename test for accuracy
williamrandolph Jul 29, 2021
247ae3e
Merge branch 'master' into system_indices_restricted_indices
williamrandolph Aug 3, 2021
a7b4bab
Remove unused method
williamrandolph Aug 4, 2021
60c0b4a
Give IndicesPermissions an automaton reference
albertzaharovits Aug 1, 2021
02bb4e1
Adjust tests for new builder
williamrandolph Aug 4, 2021
f1964fa
Precompute character run automaton
williamrandolph Aug 4, 2021
cfe2d3d
Merge branch 'master' into system_indices_restricted_indices
williamrandolph Aug 4, 2021
0a1a1fe
Add a few tests
williamrandolph Aug 4, 2021
b5f916e
Merge branch 'master' into system_indices_restricted_indices
williamrandolph Aug 5, 2021
a322e1c
Remove unneeded restricted index access
williamrandolph Aug 11, 2021
e486fb0
Merge branch 'master' into system_indices_restricted_indices
williamrandolph Aug 11, 2021
40de66b
Roll back changes to reserved roles to see what breaks in tests
williamrandolph Aug 11, 2021
678d2d4
Merge branch 'master' into system_indices_restricted_indices
williamrandolph Aug 11, 2021
ccb2398
Merge branch 'master' into system_indices_restricted_indices
williamrandolph Aug 18, 2021
60f306f
Merge branch 'master' into system_indices_restricted_indices
williamrandolph Aug 19, 2021
6393c5b
Remove allow restricted indices from client test role
williamrandolph Aug 19, 2021
e6b686c
Try using an admin client for cleaning test state
williamrandolph Aug 19, 2021
2e38e55
checkstyle
williamrandolph Aug 19, 2021
2fdbc82
Merge branch 'master' into system_indices_restricted_indices
williamrandolph Aug 19, 2021
af12dc9
Give admin client access to truststore settings
williamrandolph Aug 19, 2021
0995be0
Add explanatory comments and use warn-level logging for reset failures
williamrandolph Aug 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ protected Settings restClientSettings() {
.build();
}

@Override
protected Settings restAdminSettings() {
return restClientSettings();
}

public void testEnrollNode() throws Exception {
final NodeEnrollmentResponse nodeEnrollmentResponse =
execute(highLevelClient().security()::enrollNode, highLevelClient().security()::enrollNodeAsync, RequestOptions.DEFAULT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ protected Settings restClientSettings() {
.build();
}

@Override
protected Settings restAdminSettings() {
return restClientSettings();
}

public void testNodeEnrollment() throws Exception {
RestHighLevelClient client = highLevelClient();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.elasticsearch.client.cluster.RemoteInfoRequest;
import org.elasticsearch.client.cluster.RemoteInfoResponse;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.core.Booleans;
import org.elasticsearch.core.CheckedRunnable;
import org.elasticsearch.common.bytes.BytesReference;
Expand Down Expand Up @@ -66,6 +67,7 @@ public abstract class ESRestHighLevelClientTestCase extends ESRestTestCase {
protected static final String CONFLICT_PIPELINE_ID = "conflict_pipeline";

private static RestHighLevelClient restHighLevelClient;
private static RestHighLevelClient adminRestHighLevelClient;
private static boolean async = Booleans.parseBoolean(System.getProperty("tests.rest.async", "false"));

@Before
Expand All @@ -74,18 +76,35 @@ public void initHighLevelClient() throws IOException {
if (restHighLevelClient == null) {
restHighLevelClient = new HighLevelClient(client());
}
if (adminRestHighLevelClient == null) {
adminRestHighLevelClient = new HighLevelClient(adminClient());
}
}

@AfterClass
public static void cleanupClient() throws IOException {
IOUtils.close(restHighLevelClient);
IOUtils.close(adminRestHighLevelClient);
restHighLevelClient = null;
adminRestHighLevelClient = null;
}

protected static RestHighLevelClient highLevelClient() {
return restHighLevelClient;
}

@Override
protected Settings restAdminSettings() {
String token = basicAuthHeaderValue("admin_user", new SecureString("admin-password".toCharArray()));
return Settings.builder()
.put(ThreadContext.PREFIX + ".Authorization", token)
.build();
}

protected static RestHighLevelClient adminHighLevelClient() {
return adminRestHighLevelClient;
}

/**
* Executes the provided request using either the sync method or its async variant, both provided as functions
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ private void addModelSnapshotIndexRequests(BulkRequest bulkRequest) throws IOExc

@After
public void deleteJob() throws IOException {
new MlTestStateCleaner(logger, highLevelClient()).clearMlMetadata();
new MlTestStateCleaner(logger, adminHighLevelClient()).clearMlMetadata();
}

public void testGetModelSnapshots() throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.elasticsearch.action.ingest.DeletePipelineRequest;
import org.elasticsearch.client.core.PageParams;
import org.elasticsearch.client.feature.ResetFeaturesRequest;
import org.elasticsearch.client.feature.ResetFeaturesResponse;
import org.elasticsearch.client.ml.GetTrainedModelsStatsRequest;

import java.io.IOException;
Expand All @@ -36,7 +37,12 @@ public MlTestStateCleaner(Logger logger, RestHighLevelClient client) {
public void clearMlMetadata() throws IOException {
deleteAllTrainedModelIngestPipelines();
// This resets all features, not just ML, but they should have been getting reset between tests anyway so it shouldn't matter
client.features().resetFeatures(new ResetFeaturesRequest(), RequestOptions.DEFAULT);
ResetFeaturesResponse response = client.features().resetFeatures(new ResetFeaturesRequest(), RequestOptions.DEFAULT);
for (ResetFeaturesResponse.ResetFeatureStateStatus status : response.getFeatureResetStatuses()) {
if (status.getStatus().equals("FAILURE")) {
logger.info("Reset state response: " + status.getException());
}
}
}

@SuppressWarnings("unchecked")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

package org.elasticsearch.cluster.metadata;

import org.apache.lucene.util.automaton.Automaton;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.Version;
import org.elasticsearch.action.IndicesRequest;
Expand Down Expand Up @@ -786,6 +787,10 @@ public Predicate<String> getSystemIndexAccessPredicate() {
return systemIndexAccessLevelPredicate;
}

public Automaton getSystemNameAutomaton() {
return systemIndices.getSystemNameAutomaton();
}

public Predicate<String> getNetNewSystemIndexPredicate() {
return systemIndices::isNetNewSystemIndex;
}
Expand Down
64 changes: 44 additions & 20 deletions server/src/main/java/org/elasticsearch/indices/SystemIndices.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand All @@ -66,10 +65,12 @@ public class SystemIndices {
TASKS_FEATURE_NAME, new Feature(TASKS_FEATURE_NAME, "Manages task results", List.of(TASKS_DESCRIPTOR))
);

private final CharacterRunAutomaton systemIndexAutomaton;
private final CharacterRunAutomaton systemDataStreamIndicesAutomaton;
private final Automaton systemNameAutomaton;
private final CharacterRunAutomaton netNewSystemIndexAutomaton;
private final Predicate<String> systemDataStreamAutomaton;
private final CharacterRunAutomaton systemNameRunAutomaton;
private final CharacterRunAutomaton systemIndexRunAutomaton;
private final CharacterRunAutomaton systemDataStreamIndicesRunAutomaton;
private final Predicate<String> systemDataStreamPredicate;
private final Map<String, Feature> featureDescriptors;
private final Map<String, CharacterRunAutomaton> productToSystemIndicesMatcher;
private final ExecutorSelector executorSelector;
Expand All @@ -83,12 +84,19 @@ public SystemIndices(Map<String, Feature> pluginAndModulesDescriptors) {
featureDescriptors = buildSystemIndexDescriptorMap(pluginAndModulesDescriptors);
checkForOverlappingPatterns(featureDescriptors);
checkForDuplicateAliases(this.getSystemIndexDescriptors());
this.systemIndexAutomaton = buildIndexCharacterRunAutomaton(featureDescriptors);
Automaton systemIndexAutomata = buildIndexAutomaton(featureDescriptors);
this.systemIndexRunAutomaton = new CharacterRunAutomaton(systemIndexAutomata);
Automaton systemDataStreamIndicesAutomata = buildDataStreamBackingIndicesAutomaton(featureDescriptors);
this.systemDataStreamIndicesRunAutomaton = new CharacterRunAutomaton(systemDataStreamIndicesAutomata);
this.systemDataStreamPredicate = buildDataStreamNamePredicate(featureDescriptors);
this.netNewSystemIndexAutomaton = buildNetNewIndexCharacterRunAutomaton(featureDescriptors);
this.systemDataStreamIndicesAutomaton = buildDataStreamBackingIndicesAutomaton(featureDescriptors);
this.systemDataStreamAutomaton = buildDataStreamNamePredicate(featureDescriptors);
this.productToSystemIndicesMatcher = getProductToSystemIndicesMap(featureDescriptors);
this.executorSelector = new ExecutorSelector(this);
this.systemNameAutomaton = MinimizationOperations.minimize(
Operations.union(List.of(systemIndexAutomata, systemDataStreamIndicesAutomata, buildDataStreamAutomaton(featureDescriptors))),
Integer.MAX_VALUE
);
this.systemNameRunAutomaton = new CharacterRunAutomaton(systemNameAutomaton);
}

private static void checkForDuplicateAliases(Collection<SystemIndexDescriptor> descriptors) {
Expand Down Expand Up @@ -150,7 +158,7 @@ private static Map<String, CharacterRunAutomaton> getProductToSystemIndicesMap(M
* is checked against index names, aliases, data stream names, and the names of indices that back a system data stream.
*/
public boolean isSystemName(String name) {
return isSystemIndex(name) || isSystemDataStream(name) || isSystemIndexBackingDataStream(name);
return systemNameRunAutomaton.run(name);
}

/**
Expand All @@ -169,22 +177,30 @@ public boolean isSystemIndex(Index index) {
* @return true if the index name matches a pattern from a {@link SystemIndexDescriptor}
*/
public boolean isSystemIndex(String indexName) {
return systemIndexAutomaton.run(indexName);
return systemIndexRunAutomaton.run(indexName);
}

/**
* Determines whether the provided name matches that of a system data stream that has been defined by a
* {@link SystemDataStreamDescriptor}
*/
public boolean isSystemDataStream(String name) {
return systemDataStreamAutomaton.test(name);
return systemDataStreamPredicate.test(name);
}

/**
* Determines whether the provided name matches that of an index that backs a system data stream.
*/
public boolean isSystemIndexBackingDataStream(String name) {
return systemDataStreamIndicesAutomaton.run(name);
return systemDataStreamIndicesRunAutomaton.run(name);
}

/**
* @return An {@link Automaton} that tests whether strings are names of system indices, aliases, or
* data streams.
*/
public Automaton getSystemNameAutomaton() {
williamrandolph marked this conversation as resolved.
Show resolved Hide resolved
return systemNameAutomaton;
}

public boolean isNetNewSystemIndex(String indexName) {
Expand Down Expand Up @@ -293,11 +309,11 @@ public Map<String, Feature> getFeatures() {
return featureDescriptors;
}

private static CharacterRunAutomaton buildIndexCharacterRunAutomaton(Map<String, Feature> descriptors) {
private static Automaton buildIndexAutomaton(Map<String, Feature> descriptors) {
Optional<Automaton> automaton = descriptors.values().stream()
.map(SystemIndices::featureToIndexAutomaton)
.reduce(Operations::union);
return new CharacterRunAutomaton(MinimizationOperations.minimize(automaton.orElse(EMPTY), Integer.MAX_VALUE));
return MinimizationOperations.minimize(automaton.orElse(EMPTY), Integer.MAX_VALUE);
}

private static CharacterRunAutomaton buildNetNewIndexCharacterRunAutomaton(Map<String, Feature> featureDescriptors) {
Expand All @@ -317,19 +333,26 @@ private static Automaton featureToIndexAutomaton(Feature feature) {
return systemIndexAutomaton.orElse(EMPTY);
}

private static Predicate<String> buildDataStreamNamePredicate(Map<String, Feature> descriptors) {
Set<String> systemDataStreamNames = descriptors.values().stream()
private static Automaton buildDataStreamAutomaton(Map<String, Feature> descriptors) {
williamrandolph marked this conversation as resolved.
Show resolved Hide resolved
Optional<Automaton> automaton = descriptors.values().stream()
.flatMap(feature -> feature.getDataStreamDescriptors().stream())
.map(SystemDataStreamDescriptor::getDataStreamName)
.collect(Collectors.toUnmodifiableSet());
return systemDataStreamNames::contains;
.map(dsName -> SystemIndexDescriptor.buildAutomaton(dsName, null))
.reduce(Operations::union);

return automaton.isPresent() ? MinimizationOperations.minimize(automaton.get(), Integer.MAX_VALUE) : EMPTY;
}

private static Predicate<String> buildDataStreamNamePredicate(Map<String, Feature> descriptors) {
CharacterRunAutomaton characterRunAutomaton = new CharacterRunAutomaton(buildDataStreamAutomaton(descriptors));
return characterRunAutomaton::run;
}

private static CharacterRunAutomaton buildDataStreamBackingIndicesAutomaton(Map<String, Feature> descriptors) {
private static Automaton buildDataStreamBackingIndicesAutomaton(Map<String, Feature> descriptors) {
Optional<Automaton> automaton = descriptors.values().stream()
.map(SystemIndices::featureToDataStreamBackingIndicesAutomaton)
.reduce(Operations::union);
return new CharacterRunAutomaton(automaton.orElse(EMPTY));
return MinimizationOperations.minimize(automaton.orElse(EMPTY), Integer.MAX_VALUE);
}

private static Automaton featureToDataStreamBackingIndicesAutomaton(Feature feature) {
Expand All @@ -343,7 +366,7 @@ private static Automaton featureToDataStreamBackingIndicesAutomaton(Feature feat
}

public SystemDataStreamDescriptor validateDataStreamAccess(String dataStreamName, ThreadContext threadContext) {
if (systemDataStreamAutomaton.test(dataStreamName)) {
if (systemDataStreamPredicate.test(dataStreamName)) {
SystemDataStreamDescriptor dataStreamDescriptor = featureDescriptors.values().stream()
.flatMap(feature -> feature.getDataStreamDescriptors().stream())
.filter(descriptor -> descriptor.getDataStreamName().equals(dataStreamName))
Expand Down Expand Up @@ -405,6 +428,7 @@ IllegalArgumentException dataStreamAccessException(@Nullable String product, Str
/**
* Determines what level of system index access should be allowed in the current context.
*
* @param threadContext the current thread context that has headers associated with the current request
* @return {@link SystemIndexAccessLevel#ALL} if unrestricted system index access should be allowed,
* {@link SystemIndexAccessLevel#RESTRICTED} if a subset of system index access should be allowed, or
* {@link SystemIndexAccessLevel#NONE} if no system index access should be allowed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ private static XContentBuilder mappings() {

public static SystemIndexDescriptor getSystemIndexDescriptor() {
return SystemIndexDescriptor.builder()
.setIndexPattern(XPackPlugin.ASYNC_RESULTS_INDEX)
.setIndexPattern(XPackPlugin.ASYNC_RESULTS_INDEX + "*")
.setDescription("Async search results")
.setPrimaryIndex(XPackPlugin.ASYNC_RESULTS_INDEX)
.setMappings(mappings())
Expand Down
Loading