Change privilege of enrich stats API to monitor (#52027) (#52196)

The remote_monitoring_user user needs to access the enrich stats API.
But the request is denied because the API is categorized under admin.
The correct privilege should be monitor.
This commit is contained in:
Yang Wang 2020-06-29 10:25:33 +10:00 committed by GitHub
parent 1817b896c9
commit 61fa7f4d22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 135 additions and 6 deletions

View File

@ -58,8 +58,7 @@ public abstract class TransportNodesAction<NodesRequest extends BaseNodesRequest
protected final ClusterService clusterService;
protected final TransportService transportService;
protected final Class<NodeResponse> nodeResponseClass;
final String transportNodeAction;
protected final String transportNodeAction;
protected TransportNodesAction(String actionName, ThreadPool threadPool,
ClusterService clusterService, TransportService transportService, ActionFilters actionFilters,
@ -138,6 +137,12 @@ public abstract class TransportNodesAction<NodesRequest extends BaseNodesRequest
request.setConcreteNodes(Arrays.stream(nodesIds).map(clusterState.nodes()::get).toArray(DiscoveryNode[]::new));
}
/**
* Get a backwards compatible transport action name
*/
protected String getTransportNodeAction(DiscoveryNode node) {
return transportNodeAction;
}
class AsyncAction {
@ -179,7 +184,7 @@ public abstract class TransportNodesAction<NodesRequest extends BaseNodesRequest
nodeRequest.setParentTask(clusterService.localNode().getId(), task.getId());
}
transportService.sendRequest(node, transportNodeAction, nodeRequest, builder.build(),
transportService.sendRequest(node, getTransportNodeAction(node), nodeRequest, builder.build(),
new TransportResponseHandler<NodeResponse>() {
@Override
public NodeResponse read(StreamInput in) throws IOException {

View File

@ -24,7 +24,11 @@ import java.util.Objects;
public class EnrichStatsAction extends ActionType<EnrichStatsAction.Response> {
public static final EnrichStatsAction INSTANCE = new EnrichStatsAction();
public static final String NAME = "cluster:admin/xpack/enrich/stats";
public static final String NAME = "cluster:monitor/xpack/enrich/stats";
/**
* The BWC_NAME was used up to 7.8.x
*/
public static final String BWC_NAME = "cluster:admin/xpack/enrich/stats";
private EnrichStatsAction() {
super(NAME, Response::new);

View File

@ -0,0 +1,26 @@
/*
*
* * 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.xpack.core.security.authz.privilege;
import org.elasticsearch.action.ActionType;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.enrich.action.EnrichStatsAction;
import org.elasticsearch.xpack.core.security.authz.permission.ClusterPermission;
public class ClusterPrivilegeTests extends ESTestCase {
public void testMonitorPrivilegeWillGrantActions() {
assertGranted(ClusterPrivilegeResolver.MONITOR, EnrichStatsAction.INSTANCE);
}
public static void assertGranted(ClusterPrivilege clusterPrivilege, ActionType<?> actionType) {
assertTrue(clusterPrivilege.buildPermission(ClusterPermission.builder()).build().check(actionType.name(), null, null));
}
}

View File

@ -5,9 +5,11 @@
*/
package org.elasticsearch.xpack.enrich.action;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionType;
import org.elasticsearch.action.FailedNodeException;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.ChannelActionListener;
import org.elasticsearch.action.support.nodes.BaseNodeRequest;
import org.elasticsearch.action.support.nodes.BaseNodeResponse;
import org.elasticsearch.action.support.nodes.BaseNodesRequest;
@ -20,7 +22,9 @@ import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportChannel;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.xpack.core.enrich.action.EnrichStatsAction;
import org.elasticsearch.xpack.core.enrich.action.EnrichStatsAction.Response.CoordinatorStats;
@ -35,7 +39,11 @@ import java.util.List;
public class EnrichCoordinatorStatsAction extends ActionType<EnrichCoordinatorStatsAction.Response> {
public static final EnrichCoordinatorStatsAction INSTANCE = new EnrichCoordinatorStatsAction();
public static final String NAME = "cluster:admin/xpack/enrich/coordinator_stats";
public static final String NAME = "cluster:monitor/xpack/enrich/coordinator_stats";
/**
* The BWC_NAME was used up to 7.8.x
*/
public static final String BWC_NAME = "cluster:admin/xpack/enrich/coordinator_stats";
private EnrichCoordinatorStatsAction() {
super(NAME, Response::new);
@ -133,6 +141,24 @@ public class EnrichCoordinatorStatsAction extends ActionType<EnrichCoordinatorSt
NodeResponse.class
);
this.coordinator = coordinator;
transportService.registerRequestHandler(
EnrichCoordinatorStatsAction.BWC_NAME + "[n]",
ThreadPool.Names.SAME,
NodeRequest::new,
(NodeRequest request, TransportChannel channel, Task task) -> channel.sendResponse(nodeOperation(request, task))
);
transportService.registerRequestHandler(
EnrichCoordinatorStatsAction.BWC_NAME,
ThreadPool.Names.SAME,
false,
true,
Request::new,
(final Request request, final TransportChannel channel, Task task) -> execute(
task,
request,
new ChannelActionListener<>(channel, EnrichCoordinatorStatsAction.BWC_NAME, request)
)
);
}
@Override
@ -161,6 +187,11 @@ public class EnrichCoordinatorStatsAction extends ActionType<EnrichCoordinatorSt
DiscoveryNode node = clusterService.localNode();
return new NodeResponse(node, coordinator.getStats(node.getId()));
}
@Override
protected String getTransportNodeAction(DiscoveryNode node) {
return node.getVersion().before(Version.V_7_9_0) ? BWC_NAME + "[n]" : transportNodeAction;
}
}
}

View File

@ -5,19 +5,24 @@
*/
package org.elasticsearch.xpack.enrich.action;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.FailedNodeException;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.ChannelActionListener;
import org.elasticsearch.action.support.master.TransportMasterNodeAction;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportChannel;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.xpack.core.enrich.action.EnrichStatsAction;
import org.elasticsearch.xpack.core.enrich.action.EnrichStatsAction.Response.CoordinatorStats;
@ -52,6 +57,18 @@ public class TransportEnrichStatsAction extends TransportMasterNodeAction<Enrich
indexNameExpressionResolver
);
this.client = client;
transportService.registerRequestHandler(
EnrichStatsAction.BWC_NAME,
ThreadPool.Names.SAME,
false,
true,
EnrichStatsAction.Request::new,
(final EnrichStatsAction.Request request, final TransportChannel channel, Task task) -> execute(
task,
request,
new ChannelActionListener<>(channel, EnrichStatsAction.BWC_NAME, request)
)
);
}
@Override
@ -108,4 +125,9 @@ public class TransportEnrichStatsAction extends TransportMasterNodeAction<Enrich
protected ClusterBlockException checkBlock(EnrichStatsAction.Request request, ClusterState state) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ);
}
@Override
protected String getMasterActionName(DiscoveryNode node) {
return node.getVersion().before(Version.V_7_9_0) ? EnrichStatsAction.BWC_NAME : actionName;
}
}

View File

@ -0,0 +1,20 @@
/*
*
* * 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.xpack.enrich.action;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.security.authz.privilege.ClusterPrivilegeResolver;
import org.elasticsearch.xpack.core.security.authz.privilege.ClusterPrivilegeTests;
public class EnrichClusterPrivilegeTests extends ESTestCase {
public void testMonitorPrivilegeWillAllowAction() {
ClusterPrivilegeTests.assertGranted(ClusterPrivilegeResolver.MONITOR, EnrichCoordinatorStatsAction.INSTANCE);
}
}

View File

@ -22,7 +22,7 @@ import java.nio.file.Path;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.hamcrest.Matchers.is;
public class ClusterPrivilegeTests extends AbstractPrivilegeTestCase {
public class ClusterPrivilegeIntegrationTests extends AbstractPrivilegeTestCase {
private static final String ROLES =
"role_a:\n" +

View File

@ -128,6 +128,7 @@ for (Version bwcVersion : BuildParams.bwcVersions.wireCompatible) {
'mixed_cluster/40_ml_datafeed_crud/Put job and datafeed with aggs in mixed cluster',
'mixed_cluster/80_transform_jobs_crud/Test put batch transform on mixed cluster',
'mixed_cluster/80_transform_jobs_crud/Test put continuous transform on mixed cluster',
'mixed_cluster/110_enrich/Enrich stats query smoke test for mixed cluster',
]
// transform in mixed cluster is effectively disabled till 7.4, see gh#48019
if (Version.fromString(oldVersion).before('7.4.0')) {

View File

@ -0,0 +1,20 @@
---
"Enrich stats query smoke test for mixed cluster":
- skip:
version: " - 7.4.99"
reason: enrich not available before 7.5.0
features: node_selector
- do:
node_selector:
version: " - 7.8.99"
enrich.stats: {}
- length: { coordinator_stats: 3 }
- do:
node_selector:
version: " 7.9.0 - "
enrich.stats: {}
- length: { coordinator_stats: 3 }