Skip to content

Commit 21b9170

Browse files
authored
Security: Remove SecurityLifecycleService (elastic#30526)
This commit removes the SecurityLifecycleService, relegating its former functions of listening for cluster state updates to SecurityIndexManager and IndexAuditTrail.
1 parent 5894e35 commit 21b9170

37 files changed

+247
-375
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;
@@ -232,7 +234,7 @@
232234
import static org.elasticsearch.cluster.metadata.IndexMetaData.INDEX_FORMAT_SETTING;
233235
import static org.elasticsearch.xpack.core.XPackSettings.HTTP_SSL_ENABLED;
234236
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_TEMPLATE_NAME;
235-
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
237+
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
236238
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.INTERNAL_INDEX_FORMAT;
237239

238240
public class Security extends Plugin implements ActionPlugin, IngestPlugin, NetworkPlugin, ClusterPlugin,
@@ -261,6 +263,8 @@ public class Security extends Plugin implements ActionPlugin, IngestPlugin, Netw
261263
private final SetOnce<ThreadContext> threadContext = new SetOnce<>();
262264
private final SetOnce<TokenService> tokenService = new SetOnce<>();
263265
private final SetOnce<SecurityActionFilter> securityActionFilter = new SetOnce<>();
266+
private final SetOnce<SecurityIndexManager> securityIndex = new SetOnce<>();
267+
private final SetOnce<IndexAuditTrail> indexAuditTrail = new SetOnce<>();
264268
private final List<BootstrapCheck> bootstrapChecks;
265269
private final List<SecurityExtension> securityExtensions = new ArrayList<>();
266270

@@ -368,7 +372,6 @@ Collection<Object> createComponents(Client client, ThreadPool threadPool, Cluste
368372
components.add(securityContext.get());
369373

370374
// audit trails construction
371-
IndexAuditTrail indexAuditTrail = null;
372375
Set<AuditTrail> auditTrails = new LinkedHashSet<>();
373376
if (XPackSettings.AUDIT_ENABLED.get(settings)) {
374377
List<String> outputs = AUDIT_OUTPUTS_SETTING.get(settings);
@@ -383,8 +386,8 @@ Collection<Object> createComponents(Client client, ThreadPool threadPool, Cluste
383386
auditTrails.add(new LoggingAuditTrail(settings, clusterService, threadPool));
384387
break;
385388
case IndexAuditTrail.NAME:
386-
indexAuditTrail = new IndexAuditTrail(settings, client, threadPool, clusterService);
387-
auditTrails.add(indexAuditTrail);
389+
indexAuditTrail.set(new IndexAuditTrail(settings, client, threadPool, clusterService));
390+
auditTrails.add(indexAuditTrail.get());
388391
break;
389392
default:
390393
throw new IllegalArgumentException("Unknown audit trail output [" + output + "]");
@@ -396,20 +399,20 @@ Collection<Object> createComponents(Client client, ThreadPool threadPool, Cluste
396399
components.add(auditTrailService);
397400
this.auditTrailService.set(auditTrailService);
398401

399-
final SecurityLifecycleService securityLifecycleService =
400-
new SecurityLifecycleService(settings, clusterService, threadPool, client, indexAuditTrail);
401-
final TokenService tokenService = new TokenService(settings, Clock.systemUTC(), client, securityLifecycleService, clusterService);
402+
securityIndex.set(new SecurityIndexManager(settings, client, SecurityIndexManager.SECURITY_INDEX_NAME, clusterService));
403+
404+
final TokenService tokenService = new TokenService(settings, Clock.systemUTC(), client, securityIndex.get(), clusterService);
402405
this.tokenService.set(tokenService);
403406
components.add(tokenService);
404407

405408
// realms construction
406-
final NativeUsersStore nativeUsersStore = new NativeUsersStore(settings, client, securityLifecycleService);
407-
final NativeRoleMappingStore nativeRoleMappingStore = new NativeRoleMappingStore(settings, client, securityLifecycleService);
409+
final NativeUsersStore nativeUsersStore = new NativeUsersStore(settings, client, securityIndex.get());
410+
final NativeRoleMappingStore nativeRoleMappingStore = new NativeRoleMappingStore(settings, client, securityIndex.get());
408411
final AnonymousUser anonymousUser = new AnonymousUser(settings);
409412
final ReservedRealm reservedRealm = new ReservedRealm(env, settings, nativeUsersStore,
410-
anonymousUser, securityLifecycleService, threadPool.getThreadContext());
413+
anonymousUser, securityIndex.get(), threadPool.getThreadContext());
411414
Map<String, Realm.Factory> realmFactories = new HashMap<>(InternalRealms.getFactories(threadPool, resourceWatcherService,
412-
getSslService(), nativeUsersStore, nativeRoleMappingStore, securityLifecycleService));
415+
getSslService(), nativeUsersStore, nativeRoleMappingStore, securityIndex.get()));
413416
for (SecurityExtension extension : securityExtensions) {
414417
Map<String, Realm.Factory> newRealms = extension.getRealms(resourceWatcherService);
415418
for (Map.Entry<String, Realm.Factory> entry : newRealms.entrySet()) {
@@ -424,7 +427,7 @@ Collection<Object> createComponents(Client client, ThreadPool threadPool, Cluste
424427
components.add(realms);
425428
components.add(reservedRealm);
426429

427-
securityLifecycleService.securityIndex().addIndexStateListener(nativeRoleMappingStore::onSecurityIndexStateChange);
430+
securityIndex.get().addIndexStateListener(nativeRoleMappingStore::onSecurityIndexStateChange);
428431

429432
AuthenticationFailureHandler failureHandler = null;
430433
String extensionName = null;
@@ -449,15 +452,15 @@ Collection<Object> createComponents(Client client, ThreadPool threadPool, Cluste
449452
components.add(authcService.get());
450453

451454
final FileRolesStore fileRolesStore = new FileRolesStore(settings, env, resourceWatcherService, getLicenseState());
452-
final NativeRolesStore nativeRolesStore = new NativeRolesStore(settings, client, getLicenseState(), securityLifecycleService);
455+
final NativeRolesStore nativeRolesStore = new NativeRolesStore(settings, client, getLicenseState(), securityIndex.get());
453456
final ReservedRolesStore reservedRolesStore = new ReservedRolesStore();
454457
List<BiConsumer<Set<String>, ActionListener<Set<RoleDescriptor>>>> rolesProviders = new ArrayList<>();
455458
for (SecurityExtension extension : securityExtensions) {
456459
rolesProviders.addAll(extension.getRolesProviders(settings, resourceWatcherService));
457460
}
458461
final CompositeRolesStore allRolesStore = new CompositeRolesStore(settings, fileRolesStore, nativeRolesStore,
459462
reservedRolesStore, rolesProviders, threadPool.getThreadContext(), getLicenseState());
460-
securityLifecycleService.securityIndex().addIndexStateListener(allRolesStore::onSecurityIndexStateChange);
463+
securityIndex.get().addIndexStateListener(allRolesStore::onSecurityIndexStateChange);
461464
// to keep things simple, just invalidate all cached entries on license change. this happens so rarely that the impact should be
462465
// minimal
463466
getLicenseState().addListener(allRolesStore::invalidateAll);
@@ -468,8 +471,6 @@ Collection<Object> createComponents(Client client, ThreadPool threadPool, Cluste
468471
components.add(allRolesStore); // for SecurityFeatureSet and clear roles cache
469472
components.add(authzService);
470473

471-
components.add(securityLifecycleService);
472-
473474
ipFilter.set(new IPFilter(settings, auditTrailService, clusterService.getClusterSettings(), getLicenseState()));
474475
components.add(ipFilter.get());
475476
DestructiveOperations destructiveOperations = new DestructiveOperations(settings, clusterService.getClusterSettings());

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

Lines changed: 0 additions & 129 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,7 +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.SecurityLifecycleService;
25+
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
2626

2727
import java.time.Instant;
2828
import java.time.temporal.ChronoUnit;
@@ -50,7 +50,7 @@ final class ExpiredTokenRemover extends AbstractRunnable {
5050

5151
@Override
5252
public void doRun() {
53-
SearchRequest searchRequest = new SearchRequest(SecurityLifecycleService.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);

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import org.elasticsearch.xpack.core.security.authc.pki.PkiRealmSettings;
2121
import org.elasticsearch.xpack.core.security.authc.saml.SamlRealmSettings;
2222
import org.elasticsearch.xpack.core.ssl.SSLService;
23-
import org.elasticsearch.xpack.security.SecurityLifecycleService;
2423
import org.elasticsearch.xpack.security.authc.esnative.NativeRealm;
2524
import org.elasticsearch.xpack.security.authc.esnative.NativeUsersStore;
2625
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
@@ -30,6 +29,7 @@
3029
import org.elasticsearch.xpack.security.authc.saml.SamlRealm;
3130
import org.elasticsearch.xpack.security.authc.support.RoleMappingFileBootstrapCheck;
3231
import org.elasticsearch.xpack.security.authc.support.mapper.NativeRoleMappingStore;
32+
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
3333

3434
import java.util.ArrayList;
3535
import java.util.Arrays;
@@ -90,13 +90,13 @@ static boolean isStandardRealm(String type) {
9090
public static Map<String, Realm.Factory> getFactories(ThreadPool threadPool, ResourceWatcherService resourceWatcherService,
9191
SSLService sslService, NativeUsersStore nativeUsersStore,
9292
NativeRoleMappingStore nativeRoleMappingStore,
93-
SecurityLifecycleService securityLifecycleService) {
93+
SecurityIndexManager securityIndex) {
9494

9595
Map<String, Realm.Factory> map = new HashMap<>();
9696
map.put(FileRealmSettings.TYPE, config -> new FileRealm(config, resourceWatcherService));
9797
map.put(NativeRealmSettings.TYPE, config -> {
9898
final NativeRealm nativeRealm = new NativeRealm(config, nativeUsersStore);
99-
securityLifecycleService.securityIndex().addIndexStateListener(nativeRealm::onSecurityIndexStateChange);
99+
securityIndex.addIndexStateListener(nativeRealm::onSecurityIndexStateChange);
100100
return nativeRealm;
101101
});
102102
map.put(LdapRealmSettings.AD_TYPE, config -> new LdapRealm(LdapRealmSettings.AD_TYPE, config, sslService,

0 commit comments

Comments
 (0)