Merge remote-tracking branch 'z-areek/enhancement/use_shard_bulk_for_single_ops'

Original commit: elastic/x-pack-elasticsearch@bb4265d026
This commit is contained in:
Lee Hinman 2017-01-13 10:46:20 -07:00
commit 4db2d7101a
7 changed files with 89 additions and 19 deletions

View File

@ -13,7 +13,9 @@ import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.bulk.BulkAction;
import org.elasticsearch.action.delete.DeleteAction;
import org.elasticsearch.action.get.MultiGetAction;
import org.elasticsearch.action.index.IndexAction;
import org.elasticsearch.action.search.ClearScrollAction;
import org.elasticsearch.action.search.MultiSearchAction;
import org.elasticsearch.action.search.SearchScrollAction;
@ -74,6 +76,11 @@ public class AuthorizationService extends AbstractComponent {
private static final Predicate<String> MONITOR_INDEX_PREDICATE = IndexPrivilege.MONITOR.predicate();
private static final Predicate<String> SAME_USER_PRIVILEGE = Automatons.predicate(ChangePasswordAction.NAME, AuthenticateAction.NAME);
private static final String INDEX_SUB_REQUEST_PRIMARY = IndexAction.NAME + "[p]";
private static final String INDEX_SUB_REQUEST_REPLICA = IndexAction.NAME + "[r]";
private static final String DELETE_SUB_REQUEST_PRIMARY = DeleteAction.NAME + "[p]";
private static final String DELETE_SUB_REQUEST_REPLICA = DeleteAction.NAME + "[r]";
private final ClusterService clusterService;
private final CompositeRolesStore rolesStore;
private final AuditTrailService auditTrail;
@ -176,6 +183,17 @@ public class AuthorizationService extends AbstractComponent {
return;
}
throw denial(authentication, action, request);
} else if (isTranslatedToBulkAction(action)) {
if (request instanceof CompositeIndicesRequest == false) {
throw new IllegalStateException("Bulk translated actions must implement " + CompositeIndicesRequest.class.getSimpleName()
+ ", " + request.getClass().getSimpleName() + " doesn't");
}
// we check if the user can execute the action, without looking at indices, whici will be authorized at the shard level
if (permission.indices().check(action)) {
grant(authentication, action, request);
return;
}
throw denial(authentication, action, request);
}
// some APIs are indices requests that are not actually associated with indices. For example,
@ -318,6 +336,15 @@ public class AuthorizationService extends AbstractComponent {
action.equals("indices:data/write/reindex");
}
private static boolean isTranslatedToBulkAction(String action) {
return action.equals(IndexAction.NAME) ||
action.equals(DeleteAction.NAME) ||
action.equals(INDEX_SUB_REQUEST_PRIMARY) ||
action.equals(INDEX_SUB_REQUEST_REPLICA) ||
action.equals(DELETE_SUB_REQUEST_PRIMARY) ||
action.equals(DELETE_SUB_REQUEST_REPLICA);
}
private static boolean isScrollRelatedAction(String action) {
return action.equals(SearchScrollAction.NAME) ||
action.equals(SearchTransportService.FETCH_ID_SCROLL_ACTION_NAME) ||

View File

@ -39,10 +39,11 @@ public final class IndexPrivilege extends Privilege {
private static final Automaton ALL_AUTOMATON = patterns("indices:*");
private static final Automaton READ_AUTOMATON = patterns("indices:data/read/*");
private static final Automaton CREATE_AUTOMATON = patterns("indices:data/write/index*", PutMappingAction.NAME);
private static final Automaton CREATE_AUTOMATON = patterns("indices:data/write/index*", "indices:data/write/bulk*",
PutMappingAction.NAME);
private static final Automaton INDEX_AUTOMATON =
patterns("indices:data/write/index*", "indices:data/write/update*", PutMappingAction.NAME);
private static final Automaton DELETE_AUTOMATON = patterns("indices:data/write/delete*");
patterns("indices:data/write/index*", "indices:data/write/bulk*", "indices:data/write/update*", PutMappingAction.NAME);
private static final Automaton DELETE_AUTOMATON = patterns("indices:data/write/delete*", "indices:data/write/bulk*");
private static final Automaton WRITE_AUTOMATON = patterns("indices:data/write/*", PutMappingAction.NAME);
private static final Automaton MONITOR_AUTOMATON = patterns("indices:monitor/*");
private static final Automaton MANAGE_AUTOMATON =

View File

@ -7,7 +7,7 @@ package org.elasticsearch.action;
import org.elasticsearch.action.support.IndicesOptions;
public class MockIndicesRequest extends ActionRequest implements IndicesRequest {
public class MockIndicesRequest extends ActionRequest implements IndicesRequest, CompositeIndicesRequest {
private final String[] indices;
private final IndicesOptions indicesOptions;

View File

@ -557,9 +557,9 @@ public class AuthorizationServiceTests extends ESTestCase {
.build());
List<Tuple<String, TransportRequest>> requests = new ArrayList<>();
requests.add(new Tuple<>(DeleteAction.NAME, new DeleteRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(BulkAction.NAME + "[s]", new DeleteRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(UpdateAction.NAME, new UpdateRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(IndexAction.NAME, new IndexRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(BulkAction.NAME + "[s]", new IndexRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(SearchAction.NAME, new SearchRequest(SecurityTemplateService.SECURITY_INDEX_NAME)));
requests.add(new Tuple<>(TermVectorsAction.NAME,
new TermVectorsRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "type", "id")));
@ -642,8 +642,11 @@ public class AuthorizationServiceTests extends ESTestCase {
for (User user : Arrays.asList(XPackUser.INSTANCE, superuser)) {
List<Tuple<String, TransportRequest>> requests = new ArrayList<>();
requests.add(new Tuple<>(DeleteAction.NAME, new DeleteRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(BulkAction.NAME + "[s]",
new DeleteRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(UpdateAction.NAME, new UpdateRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(IndexAction.NAME, new IndexRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(BulkAction.NAME + "[s]", new IndexRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "type", "id")));
requests.add(new Tuple<>(SearchAction.NAME, new SearchRequest(SecurityTemplateService.SECURITY_INDEX_NAME)));
requests.add(new Tuple<>(TermVectorsAction.NAME,
new TermVectorsRequest(SecurityTemplateService.SECURITY_INDEX_NAME, "type", "id")));
@ -770,7 +773,7 @@ public class AuthorizationServiceTests extends ESTestCase {
public void testCompositeActionsIndicesAreCheckedAtTheShardLevel() {
String action;
switch(randomIntBetween(0, 5)) {
switch(randomIntBetween(0, 4)) {
case 0:
action = MultiGetAction.NAME + "[shard]";
break;
@ -787,13 +790,10 @@ public class AuthorizationServiceTests extends ESTestCase {
case 4:
action = "indices:data/read/mpercolate[s]";
break;
case 5:
//reindex delegates to index, other than search covered above
action = IndexAction.NAME;
break;
default:
throw new UnsupportedOperationException();
}
logger.info("--> action: {}", action);
TransportRequest request = new MockIndicesRequest(IndicesOptions.strictExpandOpen(), "index");
User userAllowed = new User("userAllowed", "roleAllowed");

View File

@ -9,9 +9,7 @@ import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.bulk.BulkAction;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteAction;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexAction;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateAction;
import org.elasticsearch.action.update.UpdateRequest;
@ -47,12 +45,12 @@ public class WriteActionsTests extends SecurityIntegTestCase {
client().prepareIndex("test1", "type", "id").setSource("field", "value").get();
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareIndex("index1", "type", "id").setSource("field", "value")::get,
IndexAction.NAME);
BulkAction.NAME + "[s]");
client().prepareIndex("test4", "type", "id").setSource("field", "value").get();
//the missing index gets automatically created (user has permissions for that), but indexing fails due to missing authorization
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareIndex("missing", "type", "id").setSource("field", "value")::get,
IndexAction.NAME);
BulkAction.NAME + "[s]");
}
public void testDelete() {
@ -60,11 +58,11 @@ public class WriteActionsTests extends SecurityIntegTestCase {
client().prepareIndex("test1", "type", "id").setSource("field", "value").get();
assertEquals(RestStatus.OK, client().prepareDelete("test1", "type", "id").get().status());
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareDelete("index1", "type", "id")::get, DeleteAction.NAME);
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareDelete("index1", "type", "id")::get, BulkAction.NAME + "[s]");
assertEquals(RestStatus.NOT_FOUND, client().prepareDelete("test4", "type", "id").get().status());
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareDelete("missing", "type", "id")::get, DeleteAction.NAME);
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareDelete("missing", "type", "id")::get, BulkAction.NAME + "[s]");
}
public void testUpdate() {

View File

@ -30,6 +30,27 @@
- '{"index": {"_index": "test_index", "_type": "test_type"}}'
- '{"f1": "v5_mixed", "f2": 9}'
- do:
index:
index: test_index
type: test_type
id: d10
body: {"f1": "v6_mixed", "f2": 10}
- do:
index:
index: test_index
type: test_type
id: d11
body: {"f1": "v7_mixed", "f2": 11}
- do:
index:
index: test_index
type: test_type
id: d12
body: {"f1": "v8_mixed", "f2": 12}
- do:
indices.flush:
index: test_index
@ -38,4 +59,26 @@
search:
index: test_index
- match: { hits.total: 10 } # 5 docs from old cluster, 5 docs from mixed cluster
- match: { hits.total: 13 } # 5 docs from old cluster, 8 docs from mixed cluster
- do:
delete:
index: test_index
type: test_type
id: d10
- do:
delete:
index: test_index
type: test_type
id: d11
- do:
delete:
index: test_index
type: test_type
id: d12
- do:
indices.flush:
index: test_index

View File

@ -17,7 +17,7 @@ graph_explorer:
- write
- indices:admin/refresh
- indices:admin/create
no_graph_explorer:
cluster:
@ -28,5 +28,6 @@ no_graph_explorer:
privileges:
- indices:data/read/search
- indices:data/write/index
- indices:data/write/bulk
- indices:admin/refresh
- indices:admin/create