diff --git a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/collector/node/NodeStatsCollector.java b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/collector/node/NodeStatsCollector.java index 6a4e407c4c4..c71c5be6492 100644 --- a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/collector/node/NodeStatsCollector.java +++ b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/collector/node/NodeStatsCollector.java @@ -7,8 +7,10 @@ package org.elasticsearch.marvel.agent.collector.node; import org.elasticsearch.action.admin.cluster.node.stats.NodeStats; +import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsRequest; import org.elasticsearch.action.admin.indices.stats.CommonStatsFlags; import org.elasticsearch.bootstrap.BootstrapInfo; +import org.elasticsearch.client.Client; import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider; @@ -20,6 +22,7 @@ import org.elasticsearch.marvel.agent.collector.AbstractCollector; import org.elasticsearch.marvel.agent.exporter.MarvelDoc; import org.elasticsearch.marvel.agent.settings.MarvelSettings; import org.elasticsearch.marvel.license.MarvelLicensee; +import org.elasticsearch.marvel.shield.SecuredClient; import org.elasticsearch.node.service.NodeService; import java.util.ArrayList; @@ -38,7 +41,7 @@ public class NodeStatsCollector extends AbstractCollector { public static final String NAME = "node-stats-collector"; public static final String TYPE = "node_stats"; - private final NodeService nodeService; + private final Client client; private final DiscoveryService discoveryService; private final NodeEnvironment nodeEnvironment; @@ -46,10 +49,10 @@ public class NodeStatsCollector extends AbstractCollector { @Inject public NodeStatsCollector(Settings settings, ClusterService clusterService, MarvelSettings marvelSettings, MarvelLicensee marvelLicensee, - NodeService nodeService, DiscoveryService discoveryService, NodeEnvironment nodeEnvironment, + SecuredClient client, DiscoveryService discoveryService, NodeEnvironment nodeEnvironment, DiskThresholdDecider diskThresholdDecider) { super(settings, NAME, clusterService, marvelSettings, marvelLicensee); - this.nodeService = nodeService; + this.client = client; this.discoveryService = discoveryService; this.nodeEnvironment = nodeEnvironment; this.diskThresholdDecider = diskThresholdDecider; @@ -70,7 +73,14 @@ public class NodeStatsCollector extends AbstractCollector { protected Collection doCollect() throws Exception { List results = new ArrayList<>(1); - NodeStats nodeStats = nodeService.stats(CommonStatsFlags.ALL, true, true, true, true, true, false, false, false,false, false); + NodesStatsRequest request = new NodesStatsRequest("_local"); + request.indices(CommonStatsFlags.ALL); + request.os(true); + request.jvm(true); + request.process(true); + request.threadPool(true); + request.fs(true); + NodeStats nodeStats = client.admin().cluster().nodesStats(request).actionGet().getAt(0); // Here we are calling directly the DiskThresholdDecider to retrieve the high watermark value // It would be nicer to use a settings API like documented in #6732 diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/node/NodeStatsCollectorTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/node/NodeStatsCollectorTests.java index 582df3572cc..294ec8d4e32 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/node/NodeStatsCollectorTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/node/NodeStatsCollectorTests.java @@ -15,6 +15,7 @@ import org.elasticsearch.marvel.agent.collector.AbstractCollectorTestCase; import org.elasticsearch.marvel.agent.exporter.MarvelDoc; import org.elasticsearch.marvel.agent.settings.MarvelSettings; import org.elasticsearch.marvel.license.MarvelLicensee; +import org.elasticsearch.marvel.shield.SecuredClient; import org.elasticsearch.node.service.NodeService; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; @@ -91,7 +92,7 @@ public class NodeStatsCollectorTests extends AbstractCollectorTestCase { internalCluster().getInstance(ClusterService.class, nodeId), internalCluster().getInstance(MarvelSettings.class, nodeId), internalCluster().getInstance(MarvelLicensee.class, nodeId), - internalCluster().getInstance(NodeService.class, nodeId), + internalCluster().getInstance(SecuredClient.class, nodeId), internalCluster().getInstance(DiscoveryService.class, nodeId), internalCluster().getInstance(NodeEnvironment.class, nodeId), internalCluster().getInstance(DiskThresholdDecider.class, nodeId)); diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/ShieldPlugin.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/ShieldPlugin.java index f0785966b97..5961d0487e4 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/ShieldPlugin.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/ShieldPlugin.java @@ -316,7 +316,7 @@ public class ShieldPlugin extends Plugin { } public static boolean flsDlsEnabled(Settings settings) { - return settings.getAsBoolean(DLS_FLS_ENABLED_SETTING, false); + return settings.getAsBoolean(DLS_FLS_ENABLED_SETTING, true); } private void failIfShieldQueryCacheIsNotActive(Settings settings, boolean nodeSettings) { diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/BulkRequestInterceptor.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/BulkRequestInterceptor.java index c344c9f610b..1abd5936875 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/BulkRequestInterceptor.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/BulkRequestInterceptor.java @@ -7,45 +7,49 @@ package org.elasticsearch.shield.action.interceptor; import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.action.ActionRequest; +import org.elasticsearch.action.DocumentRequest; +import org.elasticsearch.action.IndicesRequest; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.update.UpdateRequest; +import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.rest.RestStatus; -import org.elasticsearch.shield.ShieldPlugin; -import org.elasticsearch.xpack.XPackPlugin; import org.elasticsearch.shield.User; +import org.elasticsearch.shield.authz.InternalAuthorizationService; +import org.elasticsearch.shield.authz.accesscontrol.IndicesAccessControl; import org.elasticsearch.transport.TransportRequest; /** * Simular to {@link UpdateRequestInterceptor}, but checks if there are update requests embedded in a bulk request. */ -public class BulkRequestInterceptor extends FieldSecurityRequestInterceptor { +public class BulkRequestInterceptor extends AbstractComponent implements RequestInterceptor { @Inject public BulkRequestInterceptor(Settings settings) { super(settings); } - @Override public void intercept(BulkRequest request, User user) { - // FIXME remove this method override once we support bulk updates with DLS and FLS enabled overall. We'll still - // need this interceptor because individual users may still have FLS/DLS enabled and we'll want to reject only - // their requests. Also update the message to remove "document" - if (ShieldPlugin.flsDlsEnabled(this.settings)) { - disableFeatures(request); - } - } - - @Override - protected void disableFeatures(BulkRequest bulkRequest) { - for (ActionRequest actionRequest : bulkRequest.requests()) { - if (actionRequest instanceof UpdateRequest) { - throw new ElasticsearchSecurityException("Can't execute an bulk request with update requests embedded if document and field level security is enabled", RestStatus.BAD_REQUEST); + IndicesAccessControl indicesAccessControl = ((TransportRequest) request).getFromContext(InternalAuthorizationService.INDICES_PERMISSIONS_KEY); + for (IndicesRequest indicesRequest : request.subRequests()) { + for (String index : indicesRequest.indices()) { + IndicesAccessControl.IndexAccessControl indexAccessControl = indicesAccessControl.getIndexPermissions(index); + if (indexAccessControl != null) { + boolean fls = indexAccessControl.getFields() != null; + boolean dls = indexAccessControl.getQueries() != null; + if (fls || dls) { + logger.debug("intercepted request for index [{}] with field level or document level security enabled, disabling features", index); + if (indicesRequest instanceof UpdateRequest) { + throw new ElasticsearchSecurityException("Can't execute an bulk request with update requests embedded if field or document level security is enabled", RestStatus.BAD_REQUEST); + } + } + } + logger.trace("intercepted request for index [{}] with neither field level or document level security not enabled, doing nothing", index); } } } - + @Override public boolean supports(TransportRequest request) { return request instanceof BulkRequest; diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/FieldSecurityRequestInterceptor.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/FieldAndDocumentLevelSecurityRequestInterceptor.java similarity index 71% rename from elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/FieldSecurityRequestInterceptor.java rename to elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/FieldAndDocumentLevelSecurityRequestInterceptor.java index 275584270da..29387e149fc 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/FieldSecurityRequestInterceptor.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/FieldAndDocumentLevelSecurityRequestInterceptor.java @@ -22,9 +22,9 @@ import java.util.List; * Base class for interceptors that disables features when field level security is configured for indices a request * is going to execute on. */ -public abstract class FieldSecurityRequestInterceptor extends AbstractComponent implements RequestInterceptor { +public abstract class FieldAndDocumentLevelSecurityRequestInterceptor extends AbstractComponent implements RequestInterceptor { - public FieldSecurityRequestInterceptor(Settings settings) { + public FieldAndDocumentLevelSecurityRequestInterceptor(Settings settings) { super(settings); } @@ -41,13 +41,16 @@ public abstract class FieldSecurityRequestInterceptor extends AbstractC for (IndicesRequest indicesRequest : indicesRequests) { for (String index : indicesRequest.indices()) { IndicesAccessControl.IndexAccessControl indexAccessControl = indicesAccessControl.getIndexPermissions(index); - if (indexAccessControl != null && indexAccessControl.getFields() != null) { - logger.debug("intercepted request for index [{}] with field level security enabled, disabling features", index); - disableFeatures(request); - return; - } else { - logger.trace("intercepted request for index [{}] with field level security not enabled, doing nothing", index); + if (indexAccessControl != null) { + boolean fls = indexAccessControl.getFields() != null; + boolean dls = indexAccessControl.getQueries() != null; + if (fls || dls) { + logger.debug("intercepted request for index [{}] with field level or document level security enabled, disabling features", index); + disableFeatures(request); + return; + } } + logger.trace("intercepted request for index [{}] with neither field level or document level security not enabled, doing nothing", index); } } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/RealtimeRequestInterceptor.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/RealtimeRequestInterceptor.java index a80b743ee30..ace29e1e805 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/RealtimeRequestInterceptor.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/RealtimeRequestInterceptor.java @@ -5,26 +5,16 @@ */ package org.elasticsearch.shield.action.interceptor; -import org.elasticsearch.action.CompositeIndicesRequest; -import org.elasticsearch.action.IndicesRequest; import org.elasticsearch.action.RealtimeRequest; -import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.logging.support.LoggerMessageFormat; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.shield.User; -import org.elasticsearch.shield.authz.InternalAuthorizationService; -import org.elasticsearch.shield.authz.accesscontrol.IndicesAccessControl; import org.elasticsearch.transport.TransportRequest; -import java.util.Collections; -import java.util.List; - /** * If field level or document level security is enabled this interceptor disables the realtime feature of get, multi get, termsvector and * multi termsvector requests. */ -public class RealtimeRequestInterceptor extends AbstractComponent implements RequestInterceptor { +public class RealtimeRequestInterceptor extends FieldAndDocumentLevelSecurityRequestInterceptor { @Inject public RealtimeRequestInterceptor(Settings settings) { @@ -32,28 +22,8 @@ public class RealtimeRequestInterceptor extends AbstractComponent implements Req } @Override - public void intercept(RealtimeRequest request, User user) { - List indicesRequests; - if (request instanceof CompositeIndicesRequest) { - indicesRequests = ((CompositeIndicesRequest) request).subRequests(); - } else if (request instanceof IndicesRequest) { - indicesRequests = Collections.singletonList((IndicesRequest) request); - } else { - throw new IllegalArgumentException(LoggerMessageFormat.format("Expected a request of type [{}] or [{}] but got [{}] instead", CompositeIndicesRequest.class, IndicesRequest.class, request.getClass())); - } - IndicesAccessControl indicesAccessControl = ((TransportRequest) request).getFromContext(InternalAuthorizationService.INDICES_PERMISSIONS_KEY); - for (IndicesRequest indicesRequest : indicesRequests) { - for (String index : indicesRequest.indices()) { - IndicesAccessControl.IndexAccessControl indexAccessControl = indicesAccessControl.getIndexPermissions(index); - if (indexAccessControl != null && (indexAccessControl.getFields() != null || indexAccessControl.getQueries() != null)) { - logger.debug("intercepted request for index [{}] with field level or document level security enabled, forcefully disabling realtime", index); - request.realtime(false); - return; - } else { - logger.trace("intercepted request for index [{}] with field level security and document level not enabled, doing nothing", index); - } - } - } + protected void disableFeatures(RealtimeRequest realtimeRequest) { + realtimeRequest.realtime(false); } @Override diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/SearchRequestInterceptor.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/SearchRequestInterceptor.java index 4afe48f8666..e0db0d1efe7 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/SearchRequestInterceptor.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/SearchRequestInterceptor.java @@ -13,7 +13,7 @@ import org.elasticsearch.transport.TransportRequest; /** * If field level security is enabled this interceptor disables the request cache for search requests. */ -public class SearchRequestInterceptor extends FieldSecurityRequestInterceptor { +public class SearchRequestInterceptor extends FieldAndDocumentLevelSecurityRequestInterceptor { @Inject public SearchRequestInterceptor(Settings settings) { diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/UpdateRequestInterceptor.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/UpdateRequestInterceptor.java index 55b11bc1c7b..5043e29dd5b 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/UpdateRequestInterceptor.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/interceptor/UpdateRequestInterceptor.java @@ -13,13 +13,13 @@ import org.elasticsearch.rest.RestStatus; import org.elasticsearch.transport.TransportRequest; /** - * A request interceptor that fails update request if field level security is enabled. + * A request interceptor that fails update request if field or document level security is enabled. * - * It can be dangerous for users if document where to be update via a role that has field level security enabled, + * It can be dangerous for users if document where to be update via a role that has fls or dls enabled, * because only the fields that a role can see would be used to perform the update and without knowing the user may * remove the other fields, not visible for him, from the document being updated. */ -public class UpdateRequestInterceptor extends FieldSecurityRequestInterceptor { +public class UpdateRequestInterceptor extends FieldAndDocumentLevelSecurityRequestInterceptor { @Inject public UpdateRequestInterceptor(Settings settings) { @@ -28,7 +28,7 @@ public class UpdateRequestInterceptor extends FieldSecurityRequestInterceptor roles = FileRolesStore.parseFile(path, Collections.emptySet(), - logger, randomBoolean() ? Settings.builder().put(ShieldPlugin.DLS_FLS_ENABLED_SETTING, false).build() : Settings.EMPTY); + logger, Settings.builder().put(ShieldPlugin.DLS_FLS_ENABLED_SETTING, false).build()); assertThat(roles, notNullValue()); assertThat(roles.size(), is(7)); assertThat(roles.get("role_fields"), nullValue());