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

Move Security to use auto-managed system indices #68375

Merged
merged 10 commits into from
Feb 9, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ public String getIndexType() {
}

/**
* Checks that this descriptor can be used within this cluster, by comparing the supplied minimum
* node version to this descriptor's minimum version.
* Checks that this descriptor can be used within this cluster e.g. the cluster supports all required
* features, by comparing the supplied minimum node version to this descriptor's minimum version.
*
* @param cause the action being attempted that triggered the check. Used in the error message.
* @param actualMinimumNodeVersion the lower node version in the cluster
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterChangedEvent;
import org.elasticsearch.cluster.ClusterState;
Expand Down Expand Up @@ -126,6 +128,10 @@ public boolean isAvailable() {
return this.indexState.indexAvailable;
}

public boolean isMappingUpToDate() {
return this.indexState.mappingUpToDate;
}

public boolean isStateRecovered() {
return this.indexState != State.UNRECOVERED_STATE;
}
Expand Down Expand Up @@ -169,6 +175,7 @@ public void clusterChanged(ClusterChangedEvent event) {
final boolean isIndexUpToDate = indexMetadata == null ||
INDEX_FORMAT_SETTING.get(indexMetadata.getSettings()) == systemIndexDescriptor.getIndexFormat();
final boolean indexAvailable = checkIndexAvailable(event.state());
final boolean mappingIsUpToDate = indexMetadata == null || checkIndexMappingUpToDate(event.state());
final Version mappingVersion = oldestIndexMappingVersion(event.state());
final String concreteIndexName = indexMetadata == null
? systemIndexDescriptor.getPrimaryIndex()
Expand All @@ -188,8 +195,8 @@ public void clusterChanged(ClusterChangedEvent event) {
final IndexRoutingTable routingTable = event.state().getRoutingTable().index(indexMetadata.getIndex());
indexHealth = new ClusterIndexHealth(indexMetadata, routingTable).getStatus();
}
final State newState = new State(creationTime, isIndexUpToDate, indexAvailable, mappingVersion,
concreteIndexName, indexHealth, indexState);
final State newState = new State(creationTime, isIndexUpToDate, indexAvailable, mappingIsUpToDate, mappingVersion,
concreteIndexName, indexHealth, indexState, event.state().nodes().getMinNodeVersion());
this.indexState = newState;

if (newState.equals(previousState) == false) {
Expand Down Expand Up @@ -219,6 +226,19 @@ private boolean checkIndexAvailable(ClusterState state) {
}
}

private boolean checkIndexMappingUpToDate(ClusterState clusterState) {
return checkIndexMappingVersionMatches(clusterState, Version.CURRENT::equals);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be onOrAfter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good catch 👍

}

private boolean checkIndexMappingVersionMatches(ClusterState clusterState, Predicate<Version> predicate) {
return checkIndexMappingVersionMatches(this.systemIndexDescriptor.getAliasName(), clusterState, logger, predicate);
}

public static boolean checkIndexMappingVersionMatches(String indexName, ClusterState clusterState, Logger logger,
Predicate<Version> predicate) {
return loadIndexMappingVersions(indexName, clusterState, logger).stream().allMatch(predicate);
}

private Version oldestIndexMappingVersion(ClusterState clusterState) {
final Set<Version> versions = loadIndexMappingVersions(systemIndexDescriptor.getAliasName(), clusterState, logger);
return versions.stream().min(Version::compareTo).orElse(null);
Expand Down Expand Up @@ -346,6 +366,31 @@ public void onFailure(Exception e) {
}
}
}, client.admin().indices()::create);
} else if (indexState.mappingUpToDate == false) {
final String error = systemIndexDescriptor.checkMinimumNodeVersion("create index", indexState.minimumNodeVersion);
if (error != null) {
consumer.accept(new IllegalStateException(error));
} else {
logger.info(
"Index [{}] (alias [{}]) is not up to date. Updating mapping",
indexState.concreteIndexName,
systemIndexDescriptor.getAliasName()
);
PutMappingRequest request = new PutMappingRequest(indexState.concreteIndexName).source(
systemIndexDescriptor.getMappings(),
XContentType.JSON
).type(MapperService.SINGLE_MAPPING_NAME);
executeAsyncWithOrigin(client.threadPool().getThreadContext(), systemIndexDescriptor.getOrigin(), request,
ActionListener.<AcknowledgedResponse>wrap(putMappingResponse -> {
if (putMappingResponse.isAcknowledged()) {
andThen.run();
} else {
consumer.accept(new IllegalStateException("put mapping request was not acknowledged"));
}
}, consumer),
client.admin().indices()::putMapping
);
}
} else {
andThen.run();
}
Expand Down Expand Up @@ -373,24 +418,29 @@ public static boolean isIndexDeleted(State previousState, State currentState) {
* State of the security index.
*/
public static class State {
public static final State UNRECOVERED_STATE = new State(null, false, false, null, null, null, null);
public static final State UNRECOVERED_STATE = new State(null, false, false, false, null, null, null, null, null);
public final Instant creationTime;
public final boolean isIndexUpToDate;
public final boolean indexAvailable;
public final boolean mappingUpToDate;
public final Version mappingVersion;
public final String concreteIndexName;
public final ClusterHealthStatus indexHealth;
public final IndexMetadata.State indexState;
public final Version minimumNodeVersion;

public State(Instant creationTime, boolean isIndexUpToDate, boolean indexAvailable,
Version mappingVersion, String concreteIndexName, ClusterHealthStatus indexHealth, IndexMetadata.State indexState) {
boolean mappingUpToDate, Version mappingVersion, String concreteIndexName, ClusterHealthStatus indexHealth,
IndexMetadata.State indexState, Version minimumNodeVersion) {
this.creationTime = creationTime;
this.isIndexUpToDate = isIndexUpToDate;
this.indexAvailable = indexAvailable;
this.mappingUpToDate = mappingUpToDate;
this.mappingVersion = mappingVersion;
this.concreteIndexName = concreteIndexName;
this.indexHealth = indexHealth;
this.indexState = indexState;
this.minimumNodeVersion = minimumNodeVersion;
}

@Override
Expand All @@ -401,10 +451,12 @@ public boolean equals(Object o) {
return Objects.equals(creationTime, state.creationTime) &&
isIndexUpToDate == state.isIndexUpToDate &&
indexAvailable == state.indexAvailable &&
mappingUpToDate == state.mappingUpToDate &&
Objects.equals(mappingVersion, state.mappingVersion) &&
Objects.equals(concreteIndexName, state.concreteIndexName) &&
indexHealth == state.indexHealth &&
indexState == state.indexState;
indexState == state.indexState &&
Objects.equals(minimumNodeVersion, state.minimumNodeVersion);
}

public boolean indexExists() {
Expand All @@ -413,8 +465,8 @@ public boolean indexExists() {

@Override
public int hashCode() {
return Objects.hash(creationTime, isIndexUpToDate, indexAvailable, mappingVersion, concreteIndexName,
indexHealth);
return Objects.hash(creationTime, isIndexUpToDate, indexAvailable, mappingUpToDate, mappingVersion, concreteIndexName,
indexHealth, minimumNodeVersion);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2030,6 +2030,6 @@ private void setCompletedToTrue(AtomicBoolean completed) {

private SecurityIndexManager.State dummyState(ClusterHealthStatus indexStatus) {
return new SecurityIndexManager.State(
Instant.now(), true, true, null, concreteSecurityIndexName, indexStatus, IndexMetadata.State.OPEN);
Instant.now(), true, true, true, null, concreteSecurityIndexName, indexStatus, IndexMetadata.State.OPEN, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class NativeRealmTests extends ESTestCase {

private SecurityIndexManager.State dummyState(ClusterHealthStatus indexStatus) {
return new SecurityIndexManager.State(
Instant.now(), true, true, null, concreteSecurityIndexName, indexStatus, IndexMetadata.State.OPEN);
Instant.now(), true, true, true, null, concreteSecurityIndexName, indexStatus, IndexMetadata.State.OPEN, null);
}

public void testCacheClearOnIndexHealthChange() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ private SecurityIndexManager.State dummyState(ClusterHealthStatus indexStatus) {

private SecurityIndexManager.State indexState(boolean isUpToDate, ClusterHealthStatus healthStatus) {
return new SecurityIndexManager.State(
Instant.now(), isUpToDate, true, null, concreteSecurityIndexName, healthStatus, IndexMetadata.State.OPEN);
Instant.now(), isUpToDate, true, true, null, concreteSecurityIndexName, healthStatus, IndexMetadata.State.OPEN, null);
}

public void testCacheClearOnIndexHealthChange() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ private SecurityIndexManager.State dummyState(ClusterHealthStatus indexStatus) {

public SecurityIndexManager.State dummyIndexState(boolean isIndexUpToDate, ClusterHealthStatus healthStatus) {
return new SecurityIndexManager.State(
Instant.now(), isIndexUpToDate, true, null, concreteSecurityIndexName, healthStatus, IndexMetadata.State.OPEN);
Instant.now(), isIndexUpToDate, true, true, null, concreteSecurityIndexName, healthStatus, IndexMetadata.State.OPEN, null);
}

public void testCacheClearOnIndexHealthChange() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,8 +616,8 @@ public void testGetPrivilegesWorkWithoutCache() throws Exception {
private SecurityIndexManager.State dummyState(
String concreteSecurityIndexName, boolean isIndexUpToDate, ClusterHealthStatus healthStatus) {
return new SecurityIndexManager.State(
Instant.now(), isIndexUpToDate, true, null,
concreteSecurityIndexName, healthStatus, IndexMetadata.State.OPEN
Instant.now(), isIndexUpToDate, true, true, null,
concreteSecurityIndexName, healthStatus, IndexMetadata.State.OPEN, null
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ public void testSecurityIndexStateChangeWillInvalidateAllRegisteredInvalidators(

final SecurityIndexManager.State previousState = SecurityIndexManager.State.UNRECOVERED_STATE;
final SecurityIndexManager.State currentState = new SecurityIndexManager.State(
Instant.now(), true, true, Version.CURRENT,
".security", ClusterHealthStatus.GREEN, IndexMetadata.State.OPEN);
Instant.now(), true, true, true, Version.CURRENT,
".security", ClusterHealthStatus.GREEN, IndexMetadata.State.OPEN, null);

cacheInvalidatorRegistry.onSecurityIndexStageChange(previousState, currentState);
verify(invalidator1).invalidateAll();
Expand Down
Loading