Remove use of PreProcessModule

PreProcessModule was an alternate way to customize another module's
behavior inside plugins. The preferred (and only in the future) way to
do this is with onModule in the plugin itself. This change moves the
only two remaining users of PreProcessModule to do so in their
respective plugins. The use case was adding roles for shield
authorization, but these roles were really static, so there was no
reason they could not be configured up front.

Original commit: elastic/x-pack-elasticsearch@e67ac2dcb6
This commit is contained in:
Ryan Ernst 2015-08-21 11:55:28 -07:00
parent 204bb2accb
commit 670b9b5ce8
8 changed files with 52 additions and 117 deletions

View File

@ -22,6 +22,7 @@ import org.elasticsearch.shield.action.ShieldActionModule;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheAction;
import org.elasticsearch.shield.action.authc.cache.TransportClearRealmCacheAction;
import org.elasticsearch.shield.audit.AuditTrailModule;
import org.elasticsearch.shield.audit.index.IndexAuditUserHolder;
import org.elasticsearch.shield.authc.AuthenticationModule;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.shield.authc.Realms;
@ -171,6 +172,12 @@ public class ShieldPlugin extends Plugin {
module.addRestAction(RestShieldInfoAction.class);
}
public void onModule(AuthorizationModule module) {
if (enabled && AuditTrailModule.auditingEnabled(settings)) {
module.registerReservedRole(IndexAuditUserHolder.ROLE);
}
}
private void addUserSettings(Settings.Builder settingsBuilder) {
String authHeaderSettingName = Headers.PREFIX + "." + UsernamePasswordToken.BASIC_AUTH_HEADER;
if (settings.get(authHeaderSettingName) != null) {

View File

@ -7,15 +7,12 @@ package org.elasticsearch.shield.audit;
import com.google.common.collect.Sets;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.inject.PreProcessModule;
import org.elasticsearch.common.inject.multibindings.Multibinder;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.ShieldLifecycleService;
import org.elasticsearch.shield.audit.index.IndexAuditTrail;
import org.elasticsearch.shield.audit.index.IndexAuditUserHolder;
import org.elasticsearch.shield.audit.logfile.LoggingAuditTrail;
import org.elasticsearch.shield.authz.AuthorizationModule;
import org.elasticsearch.shield.support.AbstractShieldModule;
import java.util.Set;
@ -23,7 +20,7 @@ import java.util.Set;
/**
*
*/
public class AuditTrailModule extends AbstractShieldModule.Node implements PreProcessModule {
public class AuditTrailModule extends AbstractShieldModule.Node {
private final boolean enabled;
@ -40,6 +37,7 @@ public class AuditTrailModule extends AbstractShieldModule.Node implements PrePr
bind(AuditTrail.class).toInstance(AuditTrail.NOOP);
return;
}
indexAuditUser = new IndexAuditUserHolder();
String[] outputs = settings.getAsArray("shield.audit.outputs", new String[] { LoggingAuditTrail.NAME });
if (outputs.length == 0) {
bind(AuditTrail.class).toInstance(AuditTrail.NOOP);
@ -68,17 +66,7 @@ public class AuditTrailModule extends AbstractShieldModule.Node implements PrePr
}
}
@Override
public void processModule(Module module) {
if (enabled && module instanceof AuthorizationModule) {
if (indexAuditLoggingEnabled(settings)) {
indexAuditUser = new IndexAuditUserHolder(IndexAuditTrail.INDEX_NAME_PREFIX);
((AuthorizationModule) module).registerReservedRole(indexAuditUser.role());
}
}
}
static boolean auditingEnabled(Settings settings) {
public static boolean auditingEnabled(Settings settings) {
return settings.getAsBoolean("shield.audit.enabled", false);
}

View File

@ -20,30 +20,18 @@ public class IndexAuditUserHolder {
private static final String[] ROLE_NAMES = new String[] { "__indexing_audit_role" };
private final User user;
private final Permission.Global.Role role;
public IndexAuditUserHolder(String indexName) {
// append the index name with the '*' wildcard so that the principal can write to
// any index that starts with the given name. this allows us to rollover over
// audit indices hourly, daily, weekly, etc.
String indexPattern = indexName + "*";
this.role = Permission.Global.Role.builder(ROLE_NAMES[0])
.set(Privilege.Cluster.action(PutIndexTemplateAction.NAME))
.add(Privilege.Index.CREATE_INDEX, indexPattern)
.add(Privilege.Index.INDEX, indexPattern)
.add(Privilege.Index.action(BulkAction.NAME), indexPattern)
.build();
public static final Permission.Global.Role ROLE = Permission.Global.Role.builder(ROLE_NAMES[0])
.set(Privilege.Cluster.action(PutIndexTemplateAction.NAME))
.add(Privilege.Index.CREATE_INDEX, IndexAuditTrail.INDEX_NAME_PREFIX + "*")
.add(Privilege.Index.INDEX, IndexAuditTrail.INDEX_NAME_PREFIX + "*")
.add(Privilege.Index.action(BulkAction.NAME), IndexAuditTrail.INDEX_NAME_PREFIX + "*")
.build();
public IndexAuditUserHolder() {
this.user = new User.Simple(NAME, ROLE_NAMES);
}
public User user() {
return user;
}
public Permission.Global.Role role() {
return role;
}
}

View File

@ -69,7 +69,7 @@ public class IndexAuditTrailTests extends ShieldIntegTestCase {
public static final String SECOND_CLUSTER_NODE_PREFIX = "remote_" + SUITE_CLUSTER_NODE_PREFIX;
private static final IndexAuditUserHolder user = new IndexAuditUserHolder(IndexAuditTrail.INDEX_NAME_PREFIX);
private static final IndexAuditUserHolder user = new IndexAuditUserHolder();
private IndexNameResolver.Rollover rollover;
private IndexAuditTrail auditor;

View File

@ -14,9 +14,10 @@ import org.elasticsearch.cluster.settings.Validator;
import org.elasticsearch.common.component.LifecycleComponent;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.RestModule;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestModule;
import org.elasticsearch.script.ScriptModule;
import org.elasticsearch.shield.authz.AuthorizationModule;
import org.elasticsearch.watcher.actions.WatcherActionModule;
import org.elasticsearch.watcher.actions.email.service.InternalEmailService;
import org.elasticsearch.watcher.client.WatcherClientModule;
@ -35,7 +36,9 @@ import org.elasticsearch.watcher.rest.action.RestPutWatchAction;
import org.elasticsearch.watcher.rest.action.RestWatchServiceAction;
import org.elasticsearch.watcher.rest.action.RestWatcherInfoAction;
import org.elasticsearch.watcher.rest.action.RestWatcherStatsAction;
import org.elasticsearch.watcher.shield.ShieldIntegration;
import org.elasticsearch.watcher.shield.WatcherShieldModule;
import org.elasticsearch.watcher.shield.WatcherUserHolder;
import org.elasticsearch.watcher.support.WatcherIndexTemplateRegistry.TemplateConfig;
import org.elasticsearch.watcher.support.clock.ClockModule;
import org.elasticsearch.watcher.support.http.HttpClient;
@ -48,7 +51,6 @@ import org.elasticsearch.watcher.support.template.TemplateModule;
import org.elasticsearch.watcher.support.template.xmustache.XMustacheScriptEngineService;
import org.elasticsearch.watcher.support.validation.WatcherSettingsValidation;
import org.elasticsearch.watcher.transform.TransformModule;
import org.elasticsearch.watcher.transport.WatcherTransportModule;
import org.elasticsearch.watcher.transport.actions.ack.AckWatchAction;
import org.elasticsearch.watcher.transport.actions.ack.TransportAckWatchAction;
import org.elasticsearch.watcher.transport.actions.delete.DeleteWatchAction;
@ -134,14 +136,14 @@ public class WatcherPlugin extends Plugin {
return ImmutableList.of();
}
return ImmutableList.<Class<? extends LifecycleComponent>>of(
// the initialization service must be first in the list
// as other services may depend on one of the initialized
// constructs
InitializingService.class,
LicenseService.class,
InternalEmailService.class,
HttpClient.class,
WatcherSettingsValidation.class);
// the initialization service must be first in the list
// as other services may depend on one of the initialized
// constructs
InitializingService.class,
LicenseService.class,
InternalEmailService.class,
HttpClient.class,
WatcherSettingsValidation.class);
}
@Override
@ -195,6 +197,16 @@ public class WatcherPlugin extends Plugin {
}
}
// NOTE: The fact this signature takes a module is a hack, and effectively like the previous
// processModule in the plugin api. The problem is tight coupling between watcher and shield.
// We need to avoid trying to load the AuthorizationModule class unless we know shield integration
// is enabled. This is a temporary solution until inter-plugin-communication can be worked out.
public void onModule(Module module) {
if (enabled && ShieldIntegration.enabled(settings) && module instanceof AuthorizationModule) {
((AuthorizationModule)module).registerReservedRole(WatcherUserHolder.ROLE);
}
}
public static boolean watcherEnabled(Settings settings) {
return settings.getAsBoolean(ENABLED_SETTING, true);
}

View File

@ -6,19 +6,16 @@
package org.elasticsearch.watcher.shield;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.inject.PreProcessModule;
import org.elasticsearch.common.inject.util.Providers;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.authz.AuthorizationModule;
import org.elasticsearch.shield.authz.Privilege;
/**
*
*/
public class WatcherShieldModule extends AbstractModule implements PreProcessModule {
public class WatcherShieldModule extends AbstractModule {
private final ESLogger logger;
@ -50,13 +47,6 @@ public class WatcherShieldModule extends AbstractModule implements PreProcessMod
}
}
@Override
public void processModule(Module module) {
if (enabled && module instanceof AuthorizationModule) {
((AuthorizationModule) module).registerReservedRole(userHolder.role);
}
}
@Override
protected void configure() {
bind(ShieldIntegration.class).asEagerSingleton();

View File

@ -17,19 +17,19 @@ public class WatcherUserHolder {
static final String NAME = "__watcher_user";
static final String[] ROLE_NAMES = new String[] { "__watcher_role" };
final Permission.Global.Role role = Permission.Global.Role.builder(ROLE_NAMES[0])
.set(Privilege.Cluster.action("indices:admin/template/put"))
public static final Permission.Global.Role ROLE = Permission.Global.Role.builder(ROLE_NAMES[0])
.set(Privilege.Cluster.action("indices:admin/template/put"))
// for now, the watches will be executed under the watcher user, meaning, all actions
// taken as part of the execution will be executed on behalf of this user. this includes
// the index action, search input and search transform. For this reason the watcher user
// requires full access to all indices in the cluster.
//
// at later phases we'll want to execute the watch on behalf of the user who registers
// it. this will require some work to attache/persist that user to/with the watch.
.add(Privilege.Index.ALL, "*")
// for now, the watches will be executed under the watcher user, meaning, all actions
// taken as part of the execution will be executed on behalf of this user. this includes
// the index action, search input and search transform. For this reason the watcher user
// requires full access to all indices in the cluster.
//
// at later phases we'll want to execute the watch on behalf of the user who registers
// it. this will require some work to attache/persist that user to/with the watch.
.add(Privilege.Index.ALL, "*")
.build();
.build();
final User user = new User.Simple(NAME, ROLE_NAMES);

View File

@ -1,50 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.watcher.transport;
import org.elasticsearch.action.ActionModule;
import org.elasticsearch.watcher.transport.actions.ack.AckWatchAction;
import org.elasticsearch.watcher.transport.actions.ack.TransportAckWatchAction;
import org.elasticsearch.watcher.transport.actions.delete.DeleteWatchAction;
import org.elasticsearch.watcher.transport.actions.delete.TransportDeleteWatchAction;
import org.elasticsearch.watcher.transport.actions.get.GetWatchAction;
import org.elasticsearch.watcher.transport.actions.get.TransportGetWatchAction;
import org.elasticsearch.watcher.transport.actions.put.PutWatchAction;
import org.elasticsearch.watcher.transport.actions.put.TransportPutWatchAction;
import org.elasticsearch.watcher.transport.actions.execute.ExecuteWatchAction;
import org.elasticsearch.watcher.transport.actions.execute.TransportExecuteWatchAction;
import org.elasticsearch.watcher.transport.actions.service.WatcherServiceAction;
import org.elasticsearch.watcher.transport.actions.service.TransportWatcherServiceAction;
import org.elasticsearch.watcher.transport.actions.stats.WatcherStatsAction;
import org.elasticsearch.watcher.transport.actions.stats.TransportWatcherStatsAction;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.inject.PreProcessModule;
/**
*
*/
public class WatcherTransportModule extends AbstractModule implements PreProcessModule {
@Override
public void processModule(Module module) {
if (module instanceof ActionModule) {
ActionModule actionModule = (ActionModule) module;
actionModule.registerAction(PutWatchAction.INSTANCE, TransportPutWatchAction.class);
actionModule.registerAction(DeleteWatchAction.INSTANCE, TransportDeleteWatchAction.class);
actionModule.registerAction(GetWatchAction.INSTANCE, TransportGetWatchAction.class);
actionModule.registerAction(WatcherStatsAction.INSTANCE, TransportWatcherStatsAction.class);
actionModule.registerAction(AckWatchAction.INSTANCE, TransportAckWatchAction.class);
actionModule.registerAction(WatcherServiceAction.INSTANCE, TransportWatcherServiceAction.class);
actionModule.registerAction(ExecuteWatchAction.INSTANCE, TransportExecuteWatchAction.class);
}
}
@Override
protected void configure() {
}
}