Skip to content

Commit 4f1a547

Browse files
committed
Security: Remove SecurityLifecycleService (#30526)
This commit removes the SecurityLifecycleService, relegating its former functions of listening for cluster state updates to SecurityIndexManager and IndexAuditTrail.
1 parent ef427c5 commit 4f1a547

37 files changed

+248
-381
lines changed

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import org.apache.logging.log4j.Logger;
99
import org.apache.lucene.util.SetOnce;
10+
import org.elasticsearch.ElasticsearchTimeoutException;
1011
import org.elasticsearch.Version;
1112
import org.elasticsearch.action.ActionListener;
1213
import org.elasticsearch.action.ActionRequest;
@@ -16,6 +17,7 @@
1617
import org.elasticsearch.bootstrap.BootstrapCheck;
1718
import org.elasticsearch.client.Client;
1819
import org.elasticsearch.cluster.ClusterState;
20+
import org.elasticsearch.cluster.health.ClusterHealthStatus;
1921
import org.elasticsearch.cluster.metadata.IndexMetaData;
2022
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
2123
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
@@ -235,7 +237,7 @@
235237
import static org.elasticsearch.cluster.metadata.IndexMetaData.INDEX_FORMAT_SETTING;
236238
import static org.elasticsearch.xpack.core.XPackSettings.HTTP_SSL_ENABLED;
237239
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_TEMPLATE_NAME;
238-
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
240+
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
239241
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.INTERNAL_INDEX_FORMAT;
240242

241243
public class Security extends Plugin implements ActionPlugin, IngestPlugin, NetworkPlugin, ClusterPlugin, DiscoveryPlugin, MapperPlugin,
@@ -271,6 +273,8 @@ public class Security extends Plugin implements ActionPlugin, IngestPlugin, Netw
271273
private final SetOnce<ThreadContext> threadContext = new SetOnce<>();
272274
private final SetOnce<TokenService> tokenService = new SetOnce<>();
273275
private final SetOnce<SecurityActionFilter> securityActionFilter = new SetOnce<>();
276+
private final SetOnce<SecurityIndexManager> securityIndex = new SetOnce<>();
277+
private final SetOnce<IndexAuditTrail> indexAuditTrail = new SetOnce<>();
274278
private final List<BootstrapCheck> bootstrapChecks;
275279
private final List<SecurityExtension> securityExtensions = new ArrayList<>();
276280
private volatile boolean indicesAdminFilteredFields;
@@ -386,7 +390,6 @@ Collection<Object> createComponents(Client client, ThreadPool threadPool, Cluste
386390
components.add(securityContext.get());
387391

388392
// audit trails construction
389-
IndexAuditTrail indexAuditTrail = null;
390393
Set<AuditTrail> auditTrails = new LinkedHashSet<>();
391394
if (XPackSettings.AUDIT_ENABLED.get(settings)) {
392395
List<String> outputs = AUDIT_OUTPUTS_SETTING.get(settings);
@@ -401,8 +404,8 @@ Collection<Object> createComponents(Client client, ThreadPool threadPool, Cluste
401404
auditTrails.add(new LoggingAuditTrail(settings, clusterService, threadPool));
402405
break;
403406
case IndexAuditTrail.NAME:
404-
indexAuditTrail = new IndexAuditTrail(settings, client, threadPool, clusterService);
405-
auditTrails.add(indexAuditTrail);
407+
indexAuditTrail.set(new IndexAuditTrail(settings, client, threadPool, clusterService));
408+
auditTrails.add(indexAuditTrail.get());
406409
break;
407410
default:
408411
throw new IllegalArgumentException("Unknown audit trail output [" + output + "]");
@@ -414,20 +417,20 @@ Collection<Object> createComponents(Client client, ThreadPool threadPool, Cluste
414417
components.add(auditTrailService);
415418
this.auditTrailService.set(auditTrailService);
416419

417-
final SecurityLifecycleService securityLifecycleService =
418-
new SecurityLifecycleService(settings, clusterService, threadPool, client, indexAuditTrail);
419-
final TokenService tokenService = new TokenService(settings, Clock.systemUTC(), client, securityLifecycleService, clusterService);
420+
securityIndex.set(new SecurityIndexManager(settings, client, SecurityIndexManager.SECURITY_INDEX_NAME, clusterService));
421+
422+
final TokenService tokenService = new TokenService(settings, Clock.systemUTC(), client, securityIndex.get(), clusterService);
420423
this.tokenService.set(tokenService);
421424
components.add(tokenService);
422425

423426
// realms construction
424-
final NativeUsersStore nativeUsersStore = new NativeUsersStore(settings, client, securityLifecycleService);
425-
final NativeRoleMappingStore nativeRoleMappingStore = new NativeRoleMappingStore(settings, client, securityLifecycleService);
427+
final NativeUsersStore nativeUsersStore = new NativeUsersStore(settings, client, securityIndex.get());
428+
final NativeRoleMappingStore nativeRoleMappingStore = new NativeRoleMappingStore(settings, client, securityIndex.get());
426429
final AnonymousUser anonymousUser = new AnonymousUser(settings);
427430
final ReservedRealm reservedRealm = new ReservedRealm(env, settings, nativeUsersStore,
428-
anonymousUser, securityLifecycleService, threadPool.getThreadContext());
431+
anonymousUser, securityIndex.get(), threadPool.getThreadContext());
429432
Map<String, Realm.Factory> realmFactories = new HashMap<>(InternalRealms.getFactories(threadPool, resourceWatcherService,
430-
getSslService(), nativeUsersStore, nativeRoleMappingStore, securityLifecycleService));
433+
getSslService(), nativeUsersStore, nativeRoleMappingStore, securityIndex.get()));
431434
for (SecurityExtension extension : securityExtensions) {
432435
Map<String, Realm.Factory> newRealms = extension.getRealms(resourceWatcherService);
433436
for (Map.Entry<String, Realm.Factory> entry : newRealms.entrySet()) {
@@ -442,7 +445,7 @@ Collection<Object> createComponents(Client client, ThreadPool threadPool, Cluste
442445
components.add(realms);
443446
components.add(reservedRealm);
444447

445-
securityLifecycleService.securityIndex().addIndexStateListener(nativeRoleMappingStore::onSecurityIndexStateChange);
448+
securityIndex.get().addIndexStateListener(nativeRoleMappingStore::onSecurityIndexStateChange);
446449

447450
AuthenticationFailureHandler failureHandler = null;
448451
String extensionName = null;
@@ -466,15 +469,15 @@ Collection<Object> createComponents(Client client, ThreadPool threadPool, Cluste
466469
components.add(authcService.get());
467470

468471
final FileRolesStore fileRolesStore = new FileRolesStore(settings, env, resourceWatcherService, getLicenseState());
469-
final NativeRolesStore nativeRolesStore = new NativeRolesStore(settings, client, getLicenseState(), securityLifecycleService);
472+
final NativeRolesStore nativeRolesStore = new NativeRolesStore(settings, client, getLicenseState(), securityIndex.get());
470473
final ReservedRolesStore reservedRolesStore = new ReservedRolesStore();
471474
List<BiConsumer<Set<String>, ActionListener<Set<RoleDescriptor>>>> rolesProviders = new ArrayList<>();
472475
for (SecurityExtension extension : securityExtensions) {
473476
rolesProviders.addAll(extension.getRolesProviders(settings, resourceWatcherService));
474477
}
475478
final CompositeRolesStore allRolesStore = new CompositeRolesStore(settings, fileRolesStore, nativeRolesStore,
476479
reservedRolesStore, rolesProviders, threadPool.getThreadContext(), getLicenseState());
477-
securityLifecycleService.securityIndex().addIndexStateListener(allRolesStore::onSecurityIndexStateChange);
480+
securityIndex.get().addIndexStateListener(allRolesStore::onSecurityIndexStateChange);
478481
// to keep things simple, just invalidate all cached entries on license change. this happens so rarely that the impact should be
479482
// minimal
480483
getLicenseState().addListener(allRolesStore::invalidateAll);
@@ -485,8 +488,6 @@ Collection<Object> createComponents(Client client, ThreadPool threadPool, Cluste
485488
components.add(allRolesStore); // for SecurityFeatureSet and clear roles cache
486489
components.add(authzService);
487490

488-
components.add(securityLifecycleService);
489-
490491
ipFilter.set(new IPFilter(settings, auditTrailService, clusterService.getClusterSettings(), getLicenseState()));
491492
components.add(ipFilter.get());
492493
DestructiveOperations destructiveOperations = new DestructiveOperations(settings, clusterService.getClusterSettings());

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityLifecycleService.java

Lines changed: 0 additions & 126 deletions
This file was deleted.

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/index/IndexAuditTrail.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.elasticsearch.client.transport.TransportClient;
2121
import org.elasticsearch.cluster.ClusterChangedEvent;
2222
import org.elasticsearch.cluster.ClusterState;
23+
import org.elasticsearch.cluster.ClusterStateListener;
2324
import org.elasticsearch.cluster.metadata.AliasOrIndex;
2425
import org.elasticsearch.cluster.metadata.IndexMetaData;
2526
import org.elasticsearch.cluster.metadata.MappingMetaData;
@@ -29,12 +30,14 @@
2930
import org.elasticsearch.common.Strings;
3031
import org.elasticsearch.common.collect.Tuple;
3132
import org.elasticsearch.common.component.AbstractComponent;
33+
import org.elasticsearch.common.component.LifecycleListener;
3234
import org.elasticsearch.common.network.NetworkAddress;
3335
import org.elasticsearch.common.settings.Setting;
3436
import org.elasticsearch.common.settings.Setting.Property;
3537
import org.elasticsearch.common.settings.Settings;
3638
import org.elasticsearch.common.transport.TransportAddress;
3739
import org.elasticsearch.common.unit.TimeValue;
40+
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
3841
import org.elasticsearch.common.util.concurrent.EsExecutors;
3942
import org.elasticsearch.common.util.concurrent.ThreadContext;
4043
import org.elasticsearch.common.xcontent.XContentBuilder;
@@ -110,7 +113,7 @@
110113
/**
111114
* Audit trail implementation that writes events into an index.
112115
*/
113-
public class IndexAuditTrail extends AbstractComponent implements AuditTrail {
116+
public class IndexAuditTrail extends AbstractComponent implements AuditTrail, ClusterStateListener {
114117

115118
public static final String NAME = "index";
116119
public static final String DOC_TYPE = "doc";
@@ -199,13 +202,43 @@ public IndexAuditTrail(Settings settings, Client client, ThreadPool threadPool,
199202
} else {
200203
this.client = initializeRemoteClient(settings, logger);
201204
}
205+
clusterService.addListener(this);
206+
clusterService.addLifecycleListener(new LifecycleListener() {
207+
@Override
208+
public void beforeStop() {
209+
stop();
210+
}
211+
});
202212

203213
}
204214

205215
public State state() {
206216
return state.get();
207217
}
208218

219+
@Override
220+
public void clusterChanged(ClusterChangedEvent event) {
221+
try {
222+
if (state() == IndexAuditTrail.State.INITIALIZED && canStart(event)) {
223+
threadPool.generic().execute(new AbstractRunnable() {
224+
225+
@Override
226+
public void onFailure(Exception throwable) {
227+
logger.error("failed to start index audit trail services", throwable);
228+
assert false : "security lifecycle services startup failed";
229+
}
230+
231+
@Override
232+
public void doRun() {
233+
start();
234+
}
235+
});
236+
}
237+
} catch (Exception e) {
238+
logger.error("failed to start index audit trail", e);
239+
}
240+
}
241+
209242
/**
210243
* This method determines if this service can be started based on the state in the {@link ClusterChangedEvent} and
211244
* if the node is the master or not. When using remote indexing, a call to the remote cluster will be made to retrieve

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ExpiredTokenRemover.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.elasticsearch.index.reindex.ScrollableHitSource;
2323
import org.elasticsearch.threadpool.ThreadPool;
2424
import org.elasticsearch.threadpool.ThreadPool.Names;
25+
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
2526

2627
import java.time.Instant;
2728
import java.time.temporal.ChronoUnit;
@@ -30,7 +31,6 @@
3031
import static org.elasticsearch.action.support.TransportActions.isShardNotAvailableException;
3132
import static org.elasticsearch.xpack.core.ClientHelper.SECURITY_ORIGIN;
3233
import static org.elasticsearch.xpack.core.ClientHelper.executeAsyncWithOrigin;
33-
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
3434

3535
/**
3636
* Responsible for cleaning the invalidated tokens from the invalidated tokens index.
@@ -50,7 +50,7 @@ final class ExpiredTokenRemover extends AbstractRunnable {
5050

5151
@Override
5252
public void doRun() {
53-
SearchRequest searchRequest = new SearchRequest(SECURITY_INDEX_NAME);
53+
SearchRequest searchRequest = new SearchRequest(SecurityIndexManager.SECURITY_INDEX_NAME);
5454
DeleteByQueryRequest expiredDbq = new DeleteByQueryRequest(searchRequest);
5555
if (timeout != TimeValue.MINUS_ONE) {
5656
expiredDbq.setTimeout(timeout);

0 commit comments

Comments
 (0)