Support allowNoIndices option in security plugin

Supporting allowNoIndices means that the security plugin has a behaviour much more similar to vanilla es when dealing with wildcard expressions that match no indices, or empty clusters. The default for most request is to allow no indices, but security plugin could only disallow no indices all the time up until now.

The technical problem was that when anything gets resolved to an empty set of indices, we couldn't let that go through to es core, as that would become resolved to all indices by es core, which would be a security hole. We have now found a way though to replace an empty set of indices with something that es core will for sure resolve to no indices, so we can let the request through. We simply replace empty indices with '-*'.

Multi apis requests (e.g. _msearch) have yet to be fixed, as all their indices end up in the same bucket while they should each be authorized separately, so that every specific item can fail or be let through.

Original commit: elastic/x-pack-elasticsearch@0f67a0bfea
This commit is contained in:
javanna 2016-09-30 14:41:54 +02:00 committed by Luca Cavanna
parent 9b46b34bed
commit d27c4bee82
32 changed files with 559 additions and 632 deletions

View File

@ -10,9 +10,7 @@ import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.Client; import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.xpack.XPackSettings;
import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.MonitoringSettings;
import org.elasticsearch.xpack.monitoring.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.collector.AbstractCollector;
import org.elasticsearch.xpack.monitoring.exporter.MonitoringDoc; import org.elasticsearch.xpack.monitoring.exporter.MonitoringDoc;
@ -49,29 +47,19 @@ public class IndexRecoveryCollector extends AbstractCollector {
@Override @Override
protected Collection<MonitoringDoc> doCollect() throws Exception { protected Collection<MonitoringDoc> doCollect() throws Exception {
List<MonitoringDoc> results = new ArrayList<>(1); List<MonitoringDoc> results = new ArrayList<>(1);
try { RecoveryResponse recoveryResponse = client.admin().indices().prepareRecoveries()
RecoveryResponse recoveryResponse = client.admin().indices().prepareRecoveries() .setIndices(monitoringSettings.indices())
.setIndices(monitoringSettings.indices()) .setIndicesOptions(IndicesOptions.lenientExpandOpen())
.setIndicesOptions(IndicesOptions.lenientExpandOpen()) .setActiveOnly(monitoringSettings.recoveryActiveOnly())
.setActiveOnly(monitoringSettings.recoveryActiveOnly()) .get(monitoringSettings.recoveryTimeout());
.get(monitoringSettings.recoveryTimeout());
if (recoveryResponse.hasRecoveries()) { if (recoveryResponse.hasRecoveries()) {
IndexRecoveryMonitoringDoc indexRecoveryDoc = new IndexRecoveryMonitoringDoc(monitoringId(), monitoringVersion()); IndexRecoveryMonitoringDoc indexRecoveryDoc = new IndexRecoveryMonitoringDoc(monitoringId(), monitoringVersion());
indexRecoveryDoc.setClusterUUID(clusterUUID()); indexRecoveryDoc.setClusterUUID(clusterUUID());
indexRecoveryDoc.setTimestamp(System.currentTimeMillis()); indexRecoveryDoc.setTimestamp(System.currentTimeMillis());
indexRecoveryDoc.setSourceNode(localNode()); indexRecoveryDoc.setSourceNode(localNode());
indexRecoveryDoc.setRecoveryResponse(recoveryResponse); indexRecoveryDoc.setRecoveryResponse(recoveryResponse);
results.add(indexRecoveryDoc); results.add(indexRecoveryDoc);
}
} catch (IndexNotFoundException e) {
//TODO this if should go away once the empty cluster / empty set of indices behaviour is fixed in the security plugin
if (XPackSettings.SECURITY_ENABLED.get(settings)) {
//&& IndexNameExpressionResolver.isAllIndices(Arrays.asList(monitoringSettings.indices()))) {
logger.debug("collector [{}] - unable to collect data for missing index [{}]", name(), e.getIndex());
} else {
throw e;
}
} }
return Collections.unmodifiableCollection(results); return Collections.unmodifiableCollection(results);
} }

View File

@ -12,9 +12,7 @@ import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.xpack.XPackSettings;
import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.MonitoringSettings;
import org.elasticsearch.xpack.monitoring.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.collector.AbstractCollector;
import org.elasticsearch.xpack.monitoring.exporter.MonitoringDoc; import org.elasticsearch.xpack.monitoring.exporter.MonitoringDoc;
@ -51,43 +49,33 @@ public class IndexStatsCollector extends AbstractCollector {
@Override @Override
protected Collection<MonitoringDoc> doCollect() throws Exception { protected Collection<MonitoringDoc> doCollect() throws Exception {
List<MonitoringDoc> results = new ArrayList<>(); List<MonitoringDoc> results = new ArrayList<>();
try { IndicesStatsResponse indicesStats = client.admin().indices().prepareStats()
IndicesStatsResponse indicesStats = client.admin().indices().prepareStats() .setIndices(monitoringSettings.indices())
.setIndices(monitoringSettings.indices()) .setIndicesOptions(IndicesOptions.lenientExpandOpen())
.setIndicesOptions(IndicesOptions.lenientExpandOpen()) .clear()
.clear() .setDocs(true)
.setDocs(true) .setFieldData(true)
.setFieldData(true) .setIndexing(true)
.setIndexing(true) .setMerge(true)
.setMerge(true) .setSearch(true)
.setSearch(true) .setSegments(true)
.setSegments(true) .setStore(true)
.setStore(true) .setRefresh(true)
.setRefresh(true) .setQueryCache(true)
.setQueryCache(true) .setRequestCache(true)
.setRequestCache(true) .get(monitoringSettings.indexStatsTimeout());
.get(monitoringSettings.indexStatsTimeout());
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
String clusterUUID = clusterUUID(); String clusterUUID = clusterUUID();
DiscoveryNode sourceNode = localNode(); DiscoveryNode sourceNode = localNode();
for (IndexStats indexStats : indicesStats.getIndices().values()) { for (IndexStats indexStats : indicesStats.getIndices().values()) {
IndexStatsMonitoringDoc indexStatsDoc = new IndexStatsMonitoringDoc(monitoringId(), monitoringVersion()); IndexStatsMonitoringDoc indexStatsDoc = new IndexStatsMonitoringDoc(monitoringId(), monitoringVersion());
indexStatsDoc.setClusterUUID(clusterUUID); indexStatsDoc.setClusterUUID(clusterUUID);
indexStatsDoc.setTimestamp(timestamp); indexStatsDoc.setTimestamp(timestamp);
indexStatsDoc.setSourceNode(sourceNode); indexStatsDoc.setSourceNode(sourceNode);
indexStatsDoc.setIndexStats(indexStats); indexStatsDoc.setIndexStats(indexStats);
results.add(indexStatsDoc); results.add(indexStatsDoc);
}
} catch (IndexNotFoundException e) {
//TODO this if should go away once the empty cluster / empty set of indices behaviour is fixed in the security plugin
if (XPackSettings.SECURITY_ENABLED.get(settings)) {
//&& IndexNameExpressionResolver.isAllIndices(Arrays.asList(monitoringSettings.indices()))) {
logger.debug("collector [{}] - unable to collect data for missing index [{}]", name(), e.getIndex());
} else {
throw e;
}
} }
return Collections.unmodifiableCollection(results); return Collections.unmodifiableCollection(results);
} }

View File

@ -10,9 +10,7 @@ import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.Client; import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.xpack.XPackSettings;
import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.MonitoringSettings;
import org.elasticsearch.xpack.monitoring.collector.AbstractCollector; import org.elasticsearch.xpack.monitoring.collector.AbstractCollector;
import org.elasticsearch.xpack.monitoring.exporter.MonitoringDoc; import org.elasticsearch.xpack.monitoring.exporter.MonitoringDoc;
@ -45,32 +43,21 @@ public class IndicesStatsCollector extends AbstractCollector {
@Override @Override
protected Collection<MonitoringDoc> doCollect() throws Exception { protected Collection<MonitoringDoc> doCollect() throws Exception {
try { IndicesStatsResponse indicesStats = client.admin().indices().prepareStats()
IndicesStatsResponse indicesStats = client.admin().indices().prepareStats() .setIndices(monitoringSettings.indices())
.setIndices(monitoringSettings.indices()) .setIndicesOptions(IndicesOptions.lenientExpandOpen())
.setIndicesOptions(IndicesOptions.lenientExpandOpen()) .clear()
.clear() .setDocs(true)
.setDocs(true) .setIndexing(true)
.setIndexing(true) .setSearch(true)
.setSearch(true) .setStore(true)
.setStore(true) .get(monitoringSettings.indicesStatsTimeout());
.get(monitoringSettings.indicesStatsTimeout());
IndicesStatsMonitoringDoc indicesStatsDoc = new IndicesStatsMonitoringDoc(monitoringId(), monitoringVersion()); IndicesStatsMonitoringDoc indicesStatsDoc = new IndicesStatsMonitoringDoc(monitoringId(), monitoringVersion());
indicesStatsDoc.setClusterUUID(clusterUUID()); indicesStatsDoc.setClusterUUID(clusterUUID());
indicesStatsDoc.setTimestamp(System.currentTimeMillis()); indicesStatsDoc.setTimestamp(System.currentTimeMillis());
indicesStatsDoc.setSourceNode(localNode()); indicesStatsDoc.setSourceNode(localNode());
indicesStatsDoc.setIndicesStats(indicesStats); indicesStatsDoc.setIndicesStats(indicesStats);
return Collections.singletonList(indicesStatsDoc);
return Collections.singletonList(indicesStatsDoc);
} catch (IndexNotFoundException e) {
//TODO this if should go away once the empty cluster / empty set of indices behaviour is fixed in the security plugin
if (XPackSettings.SECURITY_ENABLED.get(settings)) {
//&& IndexNameExpressionResolver.isAllIndices(Arrays.asList(monitoringSettings.indices()))) {
logger.debug("collector [{}] - unable to collect data for missing index [{}]", name(), e.getIndex());
return Collections.emptyList();
}
throw e;
}
} }
} }

View File

@ -253,6 +253,15 @@ public class AuthorizationService extends AbstractComponent {
ClusterState clusterState = clusterService.state(); ClusterState clusterState = clusterService.state();
Set<String> indexNames = resolveIndices(authentication, action, request, clusterState); Set<String> indexNames = resolveIndices(authentication, action, request, clusterState);
assert !indexNames.isEmpty() : "every indices request needs to have its indices set thus the resolved indices must not be empty"; assert !indexNames.isEmpty() : "every indices request needs to have its indices set thus the resolved indices must not be empty";
//security plugin is the only responsible for the presence of "-*", as wildcards just got resolved.
//'-*' matches no indices, hence we can simply let it go through, it will yield an empty response.
if (indexNames.size() == 1 && indexNames.contains(DefaultIndicesAndAliasesResolver.NO_INDEX)) {
setIndicesAccessControl(IndicesAccessControl.ALLOW_NO_INDICES);
grant(authentication, action, request);
return;
}
MetaData metaData = clusterState.metaData(); MetaData metaData = clusterState.metaData();
IndicesAccessControl indicesAccessControl = permission.authorize(action, indexNames, metaData); IndicesAccessControl indicesAccessControl = permission.authorize(action, indexNames, metaData);
if (!indicesAccessControl.isGranted()) { if (!indicesAccessControl.isGranted()) {

View File

@ -7,6 +7,7 @@ package org.elasticsearch.xpack.security.authz.accesscontrol;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.xpack.security.authz.indicesresolver.DefaultIndicesAndAliasesResolver;
import org.elasticsearch.xpack.security.authz.permission.FieldPermissions; import org.elasticsearch.xpack.security.authz.permission.FieldPermissions;
import java.util.Collections; import java.util.Collections;
@ -22,6 +23,9 @@ import static java.util.Collections.unmodifiableSet;
public class IndicesAccessControl { public class IndicesAccessControl {
public static final IndicesAccessControl ALLOW_ALL = new IndicesAccessControl(true, Collections.emptyMap()); public static final IndicesAccessControl ALLOW_ALL = new IndicesAccessControl(true, Collections.emptyMap());
public static final IndicesAccessControl ALLOW_NO_INDICES = new IndicesAccessControl(true,
Collections.singletonMap(DefaultIndicesAndAliasesResolver.NO_INDEX,
new IndicesAccessControl.IndexAccessControl(true, new FieldPermissions(), null)));
private final boolean granted; private final boolean granted;
private final Map<String, IndexAccessControl> indexPermissions; private final Map<String, IndexAccessControl> indexPermissions;

View File

@ -9,6 +9,7 @@ import org.elasticsearch.action.AliasesRequest;
import org.elasticsearch.action.CompositeIndicesRequest; import org.elasticsearch.action.CompositeIndicesRequest;
import org.elasticsearch.action.IndicesRequest; import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.cluster.metadata.AliasOrIndex; import org.elasticsearch.cluster.metadata.AliasOrIndex;
@ -33,6 +34,9 @@ import java.util.stream.Collectors;
public class DefaultIndicesAndAliasesResolver implements IndicesAndAliasesResolver<TransportRequest> { public class DefaultIndicesAndAliasesResolver implements IndicesAndAliasesResolver<TransportRequest> {
public static final String NO_INDEX = "-*";
private static final List<String> NO_INDICES = Collections.singletonList(NO_INDEX);
private final AuthorizationService authzService; private final AuthorizationService authzService;
private final IndexNameExpressionResolver nameExpressionResolver; private final IndexNameExpressionResolver nameExpressionResolver;
@ -76,6 +80,7 @@ public class DefaultIndicesAndAliasesResolver implements IndicesAndAliasesResolv
} }
private Set<String> resolveIndicesAndAliases(User user, String action, IndicesRequest indicesRequest, MetaData metaData) { private Set<String> resolveIndicesAndAliases(User user, String action, IndicesRequest indicesRequest, MetaData metaData) {
boolean indicesReplacedWithNoIndices = false;
final Set<String> indices; final Set<String> indices;
if (indicesRequest instanceof PutMappingRequest if (indicesRequest instanceof PutMappingRequest
&& ((PutMappingRequest) indicesRequest).getConcreteIndex() != null) { && ((PutMappingRequest) indicesRequest).getConcreteIndex() != null) {
@ -92,16 +97,41 @@ public class DefaultIndicesAndAliasesResolver implements IndicesAndAliasesResolv
final boolean replaceWildcards = indicesRequest.indicesOptions().expandWildcardsOpen() final boolean replaceWildcards = indicesRequest.indicesOptions().expandWildcardsOpen()
|| indicesRequest.indicesOptions().expandWildcardsClosed(); || indicesRequest.indicesOptions().expandWildcardsClosed();
List<String> authorizedIndicesAndAliases = authzService.authorizedIndicesAndAliases(user, action); List<String> authorizedIndicesAndAliases = authzService.authorizedIndicesAndAliases(user, action);
List<String> replacedIndices = replaceWildcardsWithAuthorizedIndices(indicesRequest.indices(),
indicesRequest.indicesOptions(), metaData, authorizedIndicesAndAliases, replaceWildcards); List<String> replacedIndices = new ArrayList<>();
if (indicesRequest.indicesOptions().ignoreUnavailable()) { // check for all and return list of authorized indices
//out of all the explicit names (expanded from wildcards and original ones that were left untouched) if (IndexNameExpressionResolver.isAllIndices(indicesList(indicesRequest.indices()))) {
//remove all the ones that the current user is not authorized for and ignore them if (replaceWildcards) {
replacedIndices = replacedIndices.stream().filter(authorizedIndicesAndAliases::contains).collect(Collectors.toList()); for (String authorizedIndex : authorizedIndicesAndAliases) {
throwExceptionIfNoIndicesWereResolved(indicesRequest.indices(), replacedIndices); if (isIndexVisible(authorizedIndex, indicesRequest.indicesOptions(), metaData)) {
replacedIndices.add(authorizedIndex);
}
}
}
// if we cannot replace wildcards the indices list stays empty. Same if there are no authorized indices.
// we honour allow_no_indices like es core does.
} else {
replacedIndices = replaceWildcardsWithAuthorizedIndices(indicesRequest.indices(),
indicesRequest.indicesOptions(), metaData, authorizedIndicesAndAliases, replaceWildcards);
if (indicesRequest.indicesOptions().ignoreUnavailable()) {
//out of all the explicit names (expanded from wildcards and original ones that were left untouched)
//remove all the ones that the current user is not authorized for and ignore them
replacedIndices = replacedIndices.stream().filter(authorizedIndicesAndAliases::contains).collect(Collectors.toList());
}
}
if (replacedIndices.isEmpty()) {
if (indicesRequest.indicesOptions().allowNoIndices()) {
//this is how we tell es core to return an empty response, we can let the request through being sure
//that the '-*' wildcard expression will be resolved to no indices. We can't let empty indices through
//as that would be resolved to _all by es core.
replacedIndices = NO_INDICES;
indicesReplacedWithNoIndices = true;
} else {
throw new IndexNotFoundException(Arrays.toString(indicesRequest.indices()));
}
} }
replaceable.indices(replacedIndices.toArray(new String[replacedIndices.size()])); replaceable.indices(replacedIndices.toArray(new String[replacedIndices.size()]));
indices = Sets.newHashSet(indicesRequest.indices()); indices = Sets.newHashSet(replacedIndices);
} else { } else {
assert !containsWildcards(indicesRequest) : assert !containsWildcards(indicesRequest) :
"There are no external requests known to support wildcards that don't support replacing their indices"; "There are no external requests known to support wildcards that don't support replacing their indices";
@ -118,7 +148,7 @@ public class DefaultIndicesAndAliasesResolver implements IndicesAndAliasesResolv
} }
if (indicesRequest instanceof AliasesRequest) { if (indicesRequest instanceof AliasesRequest) {
//special treatment for AliasesRequest since we need to replace wildcards among the specified aliases. //special treatment for AliasesRequest since we need to replace wildcards among the specified aliases too.
//AliasesRequest extends IndicesRequest.Replaceable, hence its indices have already been properly replaced. //AliasesRequest extends IndicesRequest.Replaceable, hence its indices have already been properly replaced.
AliasesRequest aliasesRequest = (AliasesRequest) indicesRequest; AliasesRequest aliasesRequest = (AliasesRequest) indicesRequest;
if (aliasesRequest.expandAliasesWildcards()) { if (aliasesRequest.expandAliasesWildcards()) {
@ -127,9 +157,16 @@ public class DefaultIndicesAndAliasesResolver implements IndicesAndAliasesResolv
(authorizedIndices, metaData)); (authorizedIndices, metaData));
aliasesRequest.aliases(aliases.toArray(new String[aliases.size()])); aliasesRequest.aliases(aliases.toArray(new String[aliases.size()]));
} }
Collections.addAll(indices, aliasesRequest.aliases()); if (indicesReplacedWithNoIndices) {
assert indicesRequest instanceof GetAliasesRequest : GetAliasesRequest.class.getSimpleName() + " is the only known " +
"request implementing " + AliasesRequest.class.getSimpleName() + " that may allow no indices. Found [" +
indicesRequest.getClass().getName() + "] which ended up with an empty set of indices.";
} else {
//if we are returning '-*' we shouldn't be adding the aliases to the list or the request will not get authorized.
//Leave only '-*' and ignore the rest, result will anyway be empty.
Collections.addAll(indices, aliasesRequest.aliases());
}
} }
return indices; return indices;
} }
@ -192,24 +229,9 @@ public class DefaultIndicesAndAliasesResolver implements IndicesAndAliasesResolv
return false; return false;
} }
//TODO Investigate reusing code from vanilla es to resolve index names and wildcards
private List<String> replaceWildcardsWithAuthorizedIndices(String[] indices, IndicesOptions indicesOptions, MetaData metaData, private List<String> replaceWildcardsWithAuthorizedIndices(String[] indices, IndicesOptions indicesOptions, MetaData metaData,
List<String> authorizedIndices, boolean replaceWildcards) { List<String> authorizedIndices, boolean replaceWildcards) {
// check for all and return list of authorized indices
if (IndexNameExpressionResolver.isAllIndices(indicesList(indices))) {
if (replaceWildcards == false) {
// if we cannot replace wildcards, then we should not set all indices
return throwExceptionIfNoIndicesWereResolved(indices, null);
}
List<String> visibleIndices = new ArrayList<>();
for (String authorizedIndex : authorizedIndices) {
if (isIndexVisible(authorizedIndex, indicesOptions, metaData)) {
visibleIndices.add(authorizedIndex);
}
}
return throwExceptionIfNoIndicesWereResolved(indices, visibleIndices);
}
//the order matters when it comes to + and - (see MetaData#convertFromWildcards) //the order matters when it comes to + and - (see MetaData#convertFromWildcards)
List<String> finalIndices = new ArrayList<>(); List<String> finalIndices = new ArrayList<>();
for (int i = 0; i < indices.length; i++) { for (int i = 0; i < indices.length; i++) {
@ -235,15 +257,22 @@ public class DefaultIndicesAndAliasesResolver implements IndicesAndAliasesResolv
} }
if (replaceWildcards && Regex.isSimpleMatchPattern(aliasOrIndex)) { if (replaceWildcards && Regex.isSimpleMatchPattern(aliasOrIndex)) {
Set<String> resolvedIndices = new HashSet<>();
for (String authorizedIndex : authorizedIndices) { for (String authorizedIndex : authorizedIndices) {
if (Regex.simpleMatch(aliasOrIndex, authorizedIndex)) { if (Regex.simpleMatch(aliasOrIndex, authorizedIndex) && isIndexVisible(authorizedIndex, indicesOptions, metaData)) {
if (minus) { resolvedIndices.add(authorizedIndex);
finalIndices.remove(authorizedIndex); }
} else { }
if (isIndexVisible(authorizedIndex, indicesOptions, metaData)) { if (resolvedIndices.isEmpty()) {
finalIndices.add(authorizedIndex); //es core honours allow_no_indices for each wildcard expression, we do the same here by throwing index not found.
} if (indicesOptions.allowNoIndices() == false) {
} throw new IndexNotFoundException(aliasOrIndex);
}
} else {
if (minus) {
finalIndices.removeAll(resolvedIndices);
} else {
finalIndices.addAll(resolvedIndices);
} }
} }
} else { } else {
@ -253,21 +282,22 @@ public class DefaultIndicesAndAliasesResolver implements IndicesAndAliasesResolv
// to ensure we catch this if it changes // to ensure we catch this if it changes
if (dateMathName != aliasOrIndex) { if (dateMathName != aliasOrIndex) {
assert dateMathName.equals(aliasOrIndex) == false; assert dateMathName.equals(aliasOrIndex) == false;
if (authorizedIndices.contains(dateMathName)) { if (authorizedIndices.contains(dateMathName) && isIndexVisible(dateMathName, indicesOptions, metaData, true)) {
if (minus) { if (minus) {
finalIndices.remove(dateMathName); finalIndices.remove(dateMathName);
} else { } else {
if (isIndexVisible(dateMathName, indicesOptions, metaData, true)) { finalIndices.add(dateMathName);
finalIndices.add(dateMathName); }
} } else {
if (indicesOptions.ignoreUnavailable() == false) {
throw new IndexNotFoundException(dateMathName);
} }
} }
} else { } else {
//MetaData#convertFromWildcards checks if the index exists here and throws IndexNotFoundException if not (based on //MetaData#convertFromWildcards checks if the index exists here and throws IndexNotFoundException if not (based on
// ignore_unavailable). // ignore_unavailable). We only add/remove the index: if the index is missing or the current user is not authorized
//Do nothing as if the index is missing but the user is not authorized to it an AuthorizationException will be thrown. // to access it either an AuthorizationException will be thrown later in AuthorizationService, or the index will be
//If the index is missing and the user is authorized to it, core will throw IndexNotFoundException later on. // removed from the list, based on the ignore_unavailable option.
//There is no problem with deferring this as we are dealing with an explicit name, not with wildcards.
if (minus) { if (minus) {
finalIndices.remove(aliasOrIndex); finalIndices.remove(aliasOrIndex);
} else { } else {
@ -276,22 +306,7 @@ public class DefaultIndicesAndAliasesResolver implements IndicesAndAliasesResolv
} }
} }
} }
return finalIndices;
return throwExceptionIfNoIndicesWereResolved(indices, finalIndices);
}
private List<String> throwExceptionIfNoIndicesWereResolved(String[] originalIndices, List<String> resolvedIndices) {
//ignore the IndicesOptions#allowNoIndices and just throw exception if the wildcards expansion to authorized
//indices resulted in no indices. This is important as we always need to replace wildcards for security reason,
//to make sure that the operation is executed on the indices that we authorized it to execute on.
//If we can't replace because we got an empty set, we can only throw exception.
//Downside of this is that a single item exception is going to make fail the composite request that holds it as a whole.
if (resolvedIndices == null || resolvedIndices.isEmpty()) {
String indexName = IndexNameExpressionResolver.isAllIndices(indicesList(originalIndices)) ? MetaData.ALL : Arrays.toString
(originalIndices);
throw new IndexNotFoundException(indexName);
}
return resolvedIndices;
} }
private static boolean isIndexVisible(String index, IndicesOptions indicesOptions, MetaData metaData) { private static boolean isIndexVisible(String index, IndicesOptions indicesOptions, MetaData metaData) {
@ -304,6 +319,7 @@ public class DefaultIndicesAndAliasesResolver implements IndicesAndAliasesResolv
if (indexMetaData == null) { if (indexMetaData == null) {
//it's an alias, ignore expandWildcardsOpen and expandWildcardsClosed. //it's an alias, ignore expandWildcardsOpen and expandWildcardsClosed.
//complicated to support those options with aliases pointing to multiple indices... //complicated to support those options with aliases pointing to multiple indices...
//TODO investigate supporting expandWildcards option for aliases too, like es core does.
return true; return true;
} }
if (indexMetaData.getState() == IndexMetaData.State.CLOSE && (indicesOptions.expandWildcardsClosed() || dateMathExpression)) { if (indexMetaData.getState() == IndexMetaData.State.CLOSE && (indicesOptions.expandWildcardsClosed() || dateMathExpression)) {

View File

@ -13,7 +13,6 @@ import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.test.SecuritySettingsSource; import org.elasticsearch.test.SecuritySettingsSource;
import org.elasticsearch.xpack.XPackSettings; import org.elasticsearch.xpack.XPackSettings;
import org.elasticsearch.xpack.monitoring.resolver.MonitoringIndexNameResolver; import org.elasticsearch.xpack.monitoring.resolver.MonitoringIndexNameResolver;
@ -96,19 +95,10 @@ public class OldMonitoringIndicesBackwardsCompatibilityIT extends AbstractOldXPa
client().admin().cluster().prepareUpdateSettings().setTransientSettings(settings).get(); client().admin().cluster().prepareUpdateSettings().setTransientSettings(settings).get();
} }
// Wait for the exporter to come online and add the aliases IndexStatsResolver resolver = new IndexStatsResolver(MonitoredSystem.ES, Settings.EMPTY);
long end = TimeUnit.SECONDS.toNanos(30) + System.nanoTime(); assertBusy(() -> assertTrue(client().admin().indices().prepareExists(resolver.indexPattern()).get().isExists()));
SearchResponse firstIndexStats; SearchResponse firstIndexStats = search(resolver, greaterThanOrEqualTo(10L));
while (true) {
try {
firstIndexStats = search(new IndexStatsResolver(MonitoredSystem.ES, Settings.EMPTY), greaterThanOrEqualTo(10L));
break;
} catch (IndexNotFoundException e) {
if (System.nanoTime() - end > 0) {
throw e;
}
}
}
// All the other aliases should have been created by now so we can assert that we have the data we saved in the bwc indexes // All the other aliases should have been created by now so we can assert that we have the data we saved in the bwc indexes
SearchResponse firstShards = search(new ShardsResolver(MonitoredSystem.ES, Settings.EMPTY), greaterThanOrEqualTo(10L)); SearchResponse firstShards = search(new ShardsResolver(MonitoredSystem.ES, Settings.EMPTY), greaterThanOrEqualTo(10L));
SearchResponse firstIndicesStats = search(new IndicesStatsResolver(MonitoredSystem.ES, Settings.EMPTY), greaterThanOrEqualTo(3L)); SearchResponse firstIndicesStats = search(new IndicesStatsResolver(MonitoredSystem.ES, Settings.EMPTY), greaterThanOrEqualTo(3L));

View File

@ -5,13 +5,14 @@
*/ */
package org.elasticsearch.xpack.monitoring.cleaner.local; package org.elasticsearch.xpack.monitoring.cleaner.local;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.InternalSettingsPlugin; import org.elasticsearch.test.InternalSettingsPlugin;
import org.elasticsearch.xpack.monitoring.exporter.local.LocalExporter;
import org.elasticsearch.xpack.monitoring.cleaner.AbstractIndicesCleanerTestCase; import org.elasticsearch.xpack.monitoring.cleaner.AbstractIndicesCleanerTestCase;
import org.elasticsearch.xpack.monitoring.exporter.local.LocalExporter;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import java.util.ArrayList; import java.util.ArrayList;
@ -47,15 +48,13 @@ public class LocalIndicesCleanerTests extends AbstractIndicesCleanerTestCase {
@Override @Override
protected void assertIndicesCount(int count) throws Exception { protected void assertIndicesCount(int count) throws Exception {
assertBusy(() -> { assertBusy(() -> {
try { //we set ignore_unavailable to true for this request as the monitoring index gets deleted concurrently with this assertion
assertThat(client().admin().indices().prepareGetSettings().get().getIndexToSettings().size(), equalTo(count)); //in some cases. When the plugin security is enabled, it expands wildcards to the existing index, which then gets deleted,
} catch (IndexNotFoundException e) { //so when es core gets the request with the explicit index name, it throws an index not found exception as that index
if (securityEnabled) { //doesn't exist anymore. If we ignore unavailable instead no error will be thrown.
assertThat(0, equalTo(count)); GetSettingsResponse getSettingsResponse = client().admin().indices().prepareGetSettings()
} else { .setIndicesOptions(IndicesOptions.fromOptions(true, true, true, true)).get();
throw e; assertThat(getSettingsResponse.getIndexToSettings().size(), equalTo(count));
}
}
}); });
} }
} }

View File

@ -52,8 +52,8 @@ public class ClusterStateCollectorTests extends AbstractCollectorTestCase {
client().prepareIndex("test", "test").setSource("num", i).get(); client().prepareIndex("test", "test").setSource("num", i).get();
} }
securedFlush(); flush();
securedRefresh(); refresh();
assertHitCount(client().prepareSearch().setSize(0).get(), nbDocs); assertHitCount(client().prepareSearch().setSize(0).get(), nbDocs);
assertMonitoringDocs(newClusterStateCollector().doCollect(), nbShards); assertMonitoringDocs(newClusterStateCollector().doCollect(), nbShards);
@ -79,8 +79,8 @@ public class ClusterStateCollectorTests extends AbstractCollectorTestCase {
} }
} }
securedFlush(); flush();
securedRefresh(); refresh();
for (int i = 0; i < nbIndices; i++) { for (int i = 0; i < nbIndices; i++) {
assertHitCount(client().prepareSearch("test-" + i).setSize(0).get(), docsPerIndex[i]); assertHitCount(client().prepareSearch("test-" + i).setSize(0).get(), docsPerIndex[i]);

View File

@ -11,7 +11,6 @@ import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.indices.recovery.RecoveryState; import org.elasticsearch.indices.recovery.RecoveryState;
import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
@ -123,37 +122,21 @@ public class IndexRecoveryCollectorTests extends AbstractCollectorTestCase {
} }
public void testEmptyCluster() throws Exception { public void testEmptyCluster() throws Exception {
final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), Strings.EMPTY_ARRAY));
Strings.EMPTY_ARRAY));
waitForNoBlocksOnNode(node); waitForNoBlocksOnNode(node);
assertThat(newIndexRecoveryCollector(node).doCollect(), hasSize(0));
try {
assertThat(newIndexRecoveryCollector(node).doCollect(), hasSize(0));
} catch (IndexNotFoundException e) {
fail("IndexNotFoundException has been thrown but it should have been swallowed by the collector");
}
} }
public void testEmptyClusterAllIndices() throws Exception { public void testEmptyClusterAllIndices() throws Exception {
final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), MetaData.ALL)); final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), MetaData.ALL));
waitForNoBlocksOnNode(node); waitForNoBlocksOnNode(node);
assertThat(newIndexRecoveryCollector(node).doCollect(), hasSize(0));
try {
assertThat(newIndexRecoveryCollector(node).doCollect(), hasSize(0));
} catch (IndexNotFoundException e) {
fail("IndexNotFoundException has been thrown but it should have been swallowed by the collector");
}
} }
public void testEmptyClusterMissingIndex() throws Exception { public void testEmptyClusterMissingIndex() throws Exception {
final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), "unknown")); final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), "unknown"));
waitForNoBlocksOnNode(node); waitForNoBlocksOnNode(node);
assertThat(newIndexRecoveryCollector(node).doCollect(), hasSize(0));
try {
assertThat(newIndexRecoveryCollector(node).doCollect(), hasSize(0));
} catch (IndexNotFoundException e) {
fail("IndexNotFoundException has been thrown but it should have been swallowed by the collector");
}
} }
private IndexRecoveryCollector newIndexRecoveryCollector(String nodeId) { private IndexRecoveryCollector newIndexRecoveryCollector(String nodeId) {

View File

@ -10,7 +10,6 @@ import org.elasticsearch.action.admin.indices.stats.IndexStats;
import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.elasticsearch.xpack.monitoring.MonitoredSystem; import org.elasticsearch.xpack.monitoring.MonitoredSystem;
@ -41,34 +40,19 @@ public class IndexStatsCollectorTests extends AbstractCollectorTestCase {
public void testEmptyCluster() throws Exception { public void testEmptyCluster() throws Exception {
final String node = internalCluster().startNode(); final String node = internalCluster().startNode();
waitForNoBlocksOnNode(node); waitForNoBlocksOnNode(node);
assertThat(newIndexStatsCollector(node).doCollect(), hasSize(0));
try {
assertThat(newIndexStatsCollector(node).doCollect(), hasSize(0));
} catch (IndexNotFoundException e) {
fail("IndexNotFoundException has been thrown but it should have been swallowed by the collector");
}
} }
public void testEmptyClusterAllIndices() throws Exception { public void testEmptyClusterAllIndices() throws Exception {
final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), MetaData.ALL)); final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), MetaData.ALL));
waitForNoBlocksOnNode(node); waitForNoBlocksOnNode(node);
assertThat(newIndexStatsCollector(node).doCollect(), hasSize(0));
try {
assertThat(newIndexStatsCollector(node).doCollect(), hasSize(0));
} catch (IndexNotFoundException e) {
fail("IndexNotFoundException has been thrown but it should have been swallowed by the collector");
}
} }
public void testEmptyClusterMissingIndex() throws Exception { public void testEmptyClusterMissingIndex() throws Exception {
final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), "unknown")); final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), "unknown"));
waitForNoBlocksOnNode(node); waitForNoBlocksOnNode(node);
assertThat(newIndexStatsCollector(node).doCollect(), hasSize(0));
try {
assertThat(newIndexStatsCollector(node).doCollect(), hasSize(0));
} catch (IndexNotFoundException e) {
fail("IndexNotFoundException has been thrown but it should have been swallowed by the collector");
}
} }
public void testIndexStatsCollectorOneIndex() throws Exception { public void testIndexStatsCollectorOneIndex() throws Exception {
@ -77,15 +61,15 @@ public class IndexStatsCollectorTests extends AbstractCollectorTestCase {
final String indexName = "one-index"; final String indexName = "one-index";
createIndex(indexName); createIndex(indexName);
securedEnsureGreen(indexName); ensureGreen(indexName);
final int nbDocs = randomIntBetween(1, 20); final int nbDocs = randomIntBetween(1, 20);
for (int i = 0; i < nbDocs; i++) { for (int i = 0; i < nbDocs; i++) {
client().prepareIndex(indexName, "test").setSource("num", i).get(); client().prepareIndex(indexName, "test").setSource("num", i).get();
} }
securedFlush(); flush();
securedRefresh(); refresh();
assertHitCount(client().prepareSearch().setSize(0).get(), nbDocs); assertHitCount(client().prepareSearch().setSize(0).get(), nbDocs);
@ -127,7 +111,7 @@ public class IndexStatsCollectorTests extends AbstractCollectorTestCase {
for (int i = 0; i < nbIndices; i++) { for (int i = 0; i < nbIndices; i++) {
String index = indexPrefix + i; String index = indexPrefix + i;
createIndex(index); createIndex(index);
securedEnsureGreen(index); ensureGreen(index);
docsPerIndex[i] = randomIntBetween(1, 20); docsPerIndex[i] = randomIntBetween(1, 20);
for (int j = 0; j < docsPerIndex[i]; j++) { for (int j = 0; j < docsPerIndex[i]; j++) {
@ -135,8 +119,8 @@ public class IndexStatsCollectorTests extends AbstractCollectorTestCase {
} }
} }
securedFlush(); flush();
securedRefresh(); refresh();
for (int i = 0; i < nbIndices; i++) { for (int i = 0; i < nbIndices; i++) {
assertHitCount(client().prepareSearch(indexPrefix + i).setSize(0).get(), docsPerIndex[i]); assertHitCount(client().prepareSearch(indexPrefix + i).setSize(0).get(), docsPerIndex[i]);

View File

@ -12,7 +12,6 @@ import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.elasticsearch.xpack.monitoring.MonitoredSystem; import org.elasticsearch.xpack.monitoring.MonitoredSystem;
@ -41,37 +40,19 @@ public class IndicesStatsCollectorTests extends AbstractCollectorTestCase {
public void testEmptyCluster() throws Exception { public void testEmptyCluster() throws Exception {
final String node = internalCluster().startNode(); final String node = internalCluster().startNode();
waitForNoBlocksOnNode(node); waitForNoBlocksOnNode(node);
assertThat(newIndicesStatsCollector(node).doCollect(), hasSize(1));
try {
assertThat(newIndicesStatsCollector(node).doCollect(), hasSize(securityEnabled ? 0 : 1));
} catch (IndexNotFoundException e) {
fail("IndexNotFoundException has been thrown but it should have been swallowed by the collector");
}
} }
public void testEmptyClusterAllIndices() throws Exception { public void testEmptyClusterAllIndices() throws Exception {
final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), MetaData.ALL)); final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), MetaData.ALL));
waitForNoBlocksOnNode(node); waitForNoBlocksOnNode(node);
assertThat(newIndicesStatsCollector(node).doCollect(), hasSize(1));
try {
assertThat(newIndicesStatsCollector(node).doCollect(), hasSize(securityEnabled ? 0 : 1));
} catch (IndexNotFoundException e) {
fail("IndexNotFoundException has been thrown but it should have been swallowed by the collector");
}
} }
@AwaitsFix(bugUrl = "https://github.com/elastic/x-plugins/issues/1250")
//this test is temporarily disabled. The security plugin honours now ignore_unavailable, but whenever there's a request left
//with an empty set of indices it throws exception. This will be fixed once security plugin honours allow_no_indices too.
public void testEmptyClusterMissingIndex() throws Exception { public void testEmptyClusterMissingIndex() throws Exception {
final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), "unknown")); final String node = internalCluster().startNode(Settings.builder().put(MonitoringSettings.INDICES.getKey(), "unknown"));
waitForNoBlocksOnNode(node); waitForNoBlocksOnNode(node);
assertThat(newIndicesStatsCollector(node).doCollect(), hasSize(1));
try {
assertThat(newIndicesStatsCollector(node).doCollect(), hasSize(1));
} catch (IndexNotFoundException e) {
fail("IndexNotFoundException has been thrown but it should have been swallowed by the collector");
}
} }
public void testIndicesStatsCollectorOneIndex() throws Exception { public void testIndicesStatsCollectorOneIndex() throws Exception {
@ -80,7 +61,7 @@ public class IndicesStatsCollectorTests extends AbstractCollectorTestCase {
final String indexName = "one-index"; final String indexName = "one-index";
createIndex(indexName); createIndex(indexName);
securedEnsureGreen(indexName); ensureGreen(indexName);
final int nbDocs = randomIntBetween(1, 20); final int nbDocs = randomIntBetween(1, 20);
@ -88,8 +69,8 @@ public class IndicesStatsCollectorTests extends AbstractCollectorTestCase {
client().prepareIndex(indexName, "test").setSource("num", i).get(); client().prepareIndex(indexName, "test").setSource("num", i).get();
} }
securedFlush(); flush();
securedRefresh(); refresh();
assertHitCount(client().prepareSearch().setSize(0).get(), nbDocs); assertHitCount(client().prepareSearch().setSize(0).get(), nbDocs);
@ -124,7 +105,7 @@ public class IndicesStatsCollectorTests extends AbstractCollectorTestCase {
for (int i = 0; i < nbIndices; i++) { for (int i = 0; i < nbIndices; i++) {
String index = indexPrefix + i; String index = indexPrefix + i;
createIndex(index); createIndex(index);
securedEnsureGreen(index); ensureGreen(index);
docsPerIndex[i] = randomIntBetween(1, 20); docsPerIndex[i] = randomIntBetween(1, 20);
for (int j = 0; j < docsPerIndex[i]; j++) { for (int j = 0; j < docsPerIndex[i]; j++) {
@ -132,8 +113,8 @@ public class IndicesStatsCollectorTests extends AbstractCollectorTestCase {
} }
} }
securedFlush(); flush();
securedRefresh(); refresh();
for (int i = 0; i < nbIndices; i++) { for (int i = 0; i < nbIndices; i++) {
assertHitCount(client().prepareSearch(indexPrefix + i).setSize(0).get(), docsPerIndex[i]); assertHitCount(client().prepareSearch(indexPrefix + i).setSize(0).get(), docsPerIndex[i]);

View File

@ -50,8 +50,8 @@ public class ShardsCollectorTests extends AbstractCollectorTestCase {
} }
waitForRelocation(); waitForRelocation();
securedEnsureGreen(); ensureGreen();
securedRefresh(); refresh();
assertHitCount(client().prepareSearch().setSize(0).get(), nbDocs); assertHitCount(client().prepareSearch().setSize(0).get(), nbDocs);
@ -108,7 +108,7 @@ public class ShardsCollectorTests extends AbstractCollectorTestCase {
} }
waitForRelocation(); waitForRelocation();
securedRefresh(); refresh();
int totalShards = 0; int totalShards = 0;
for (int i = 0; i < nbIndices; i++) { for (int i = 0; i < nbIndices; i++) {

View File

@ -67,7 +67,7 @@ public class LocalExporterTests extends MonitoringIntegTestCase {
.put("xpack.monitoring.exporters._local.type", LocalExporter.TYPE) .put("xpack.monitoring.exporters._local.type", LocalExporter.TYPE)
.put("xpack.monitoring.exporters._local.enabled", true) .put("xpack.monitoring.exporters._local.enabled", true)
.build()); .build());
securedEnsureGreen(); ensureGreen();
logger.debug("--> exporting a single monitoring doc"); logger.debug("--> exporting a single monitoring doc");
export(Collections.singletonList(newRandomMonitoringDoc())); export(Collections.singletonList(newRandomMonitoringDoc()));
@ -97,7 +97,7 @@ public class LocalExporterTests extends MonitoringIntegTestCase {
internalCluster().startNode(Settings.builder() internalCluster().startNode(Settings.builder()
.put("xpack.monitoring.exporters._local.type", LocalExporter.TYPE) .put("xpack.monitoring.exporters._local.type", LocalExporter.TYPE)
.build()); .build());
securedEnsureGreen(); ensureGreen();
// start collecting // start collecting
updateMonitoringInterval(3L, TimeUnit.SECONDS); updateMonitoringInterval(3L, TimeUnit.SECONDS);
@ -113,7 +113,7 @@ public class LocalExporterTests extends MonitoringIntegTestCase {
.put("xpack.monitoring.exporters._local.type", LocalExporter.TYPE) .put("xpack.monitoring.exporters._local.type", LocalExporter.TYPE)
.put("xpack.monitoring.exporters._local." + LocalExporter.INDEX_NAME_TIME_FORMAT_SETTING, timeFormat) .put("xpack.monitoring.exporters._local." + LocalExporter.INDEX_NAME_TIME_FORMAT_SETTING, timeFormat)
.build()); .build());
securedEnsureGreen(); ensureGreen();
LocalExporter exporter = getLocalExporter("_local"); LocalExporter exporter = getLocalExporter("_local");
@ -146,7 +146,7 @@ public class LocalExporterTests extends MonitoringIntegTestCase {
.put("xpack.monitoring.exporters._local.type", LocalExporter.TYPE) .put("xpack.monitoring.exporters._local.type", LocalExporter.TYPE)
.put("xpack.monitoring.exporters._local.enabled", true) .put("xpack.monitoring.exporters._local.enabled", true)
.build()); .build());
securedEnsureGreen(); ensureGreen();
logger.debug("--> exporting a single monitoring doc"); logger.debug("--> exporting a single monitoring doc");
export(Collections.singletonList(newRandomMonitoringDoc())); export(Collections.singletonList(newRandomMonitoringDoc()));

View File

@ -57,7 +57,7 @@ public class ClusterInfoTests extends MonitoringIntegTestCase {
} }
public void testClusterInfo() throws Exception { public void testClusterInfo() throws Exception {
securedEnsureGreen(); ensureGreen();
final String clusterUUID = client().admin().cluster().prepareState().setMetaData(true).get().getState().metaData().clusterUUID(); final String clusterUUID = client().admin().cluster().prepareState().setMetaData(true).get().getState().metaData().clusterUUID();
assertTrue(Strings.hasText(clusterUUID)); assertTrue(Strings.hasText(clusterUUID));
@ -136,8 +136,8 @@ public class ClusterInfoTests extends MonitoringIntegTestCase {
waitForMonitoringTemplates(); waitForMonitoringTemplates();
// check that the cluster_info is not indexed // check that the cluster_info is not indexed
securedFlush(); flush();
securedRefresh(); refresh();
assertHitCount(client().prepareSearch().setSize(0) assertHitCount(client().prepareSearch().setSize(0)
.setIndices(dataIndex) .setIndices(dataIndex)

View File

@ -18,7 +18,6 @@ import org.junit.After;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
@ -56,9 +55,9 @@ public class ClusterStatsTests extends MonitoringIntegTestCase {
index(indices[i], "foo", "1", jsonBuilder().startObject().field("dummy_field", 1).endObject()); index(indices[i], "foo", "1", jsonBuilder().startObject().field("dummy_field", 1).endObject());
} }
securedFlush(); flush();
securedRefresh(); refresh();
securedEnsureGreen(); ensureGreen();
// ok.. we'll start collecting now... // ok.. we'll start collecting now...
updateMonitoringInterval(3L, TimeUnit.SECONDS); updateMonitoringInterval(3L, TimeUnit.SECONDS);

View File

@ -58,8 +58,8 @@ public class IndexRecoveryTests extends MonitoringIntegTestCase {
assertBusy(new Runnable() { assertBusy(new Runnable() {
@Override @Override
public void run() { public void run() {
securedFlush(); flush();
securedRefresh(); refresh();
RecoveryResponse recoveries = client().admin().indices().prepareRecoveries().get(); RecoveryResponse recoveries = client().admin().indices().prepareRecoveries().get();
assertThat(recoveries.hasRecoveries(), is(true)); assertThat(recoveries.hasRecoveries(), is(true));
@ -95,8 +95,8 @@ public class IndexRecoveryTests extends MonitoringIntegTestCase {
} }
} }
securedFlush(); flush();
securedRefresh(); refresh();
logger.debug("--> checking that cluster_uuid field is correctly indexed"); logger.debug("--> checking that cluster_uuid field is correctly indexed");
response = client().prepareSearch().setTypes(IndexRecoveryResolver.TYPE).setSize(0).setQuery(existsQuery("cluster_uuid")).get(); response = client().prepareSearch().setTypes(IndexRecoveryResolver.TYPE).setSize(0).setQuery(existsQuery("cluster_uuid")).get();

View File

@ -17,7 +17,6 @@ import org.elasticsearch.xpack.monitoring.test.MonitoringIntegTestCase;
import org.junit.After; import org.junit.After;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThan;
@ -59,8 +58,8 @@ public class IndexStatsTests extends MonitoringIntegTestCase {
} }
} }
securedFlush(); flush();
securedRefresh(); refresh();
updateMonitoringInterval(3L, TimeUnit.SECONDS); updateMonitoringInterval(3L, TimeUnit.SECONDS);
waitForMonitoringIndices(); waitForMonitoringIndices();
@ -71,8 +70,8 @@ public class IndexStatsTests extends MonitoringIntegTestCase {
assertBusy(new Runnable() { assertBusy(new Runnable() {
@Override @Override
public void run() { public void run() {
securedFlush(indices); flush(indices);
securedRefresh(); refresh();
for (int i = 0; i < nbIndices; i++) { for (int i = 0; i < nbIndices; i++) {
SearchResponse count = client().prepareSearch() SearchResponse count = client().prepareSearch()
.setSize(0) .setSize(0)

View File

@ -59,8 +59,8 @@ public class IndicesStatsTests extends MonitoringIntegTestCase {
assertBusy(new Runnable() { assertBusy(new Runnable() {
@Override @Override
public void run() { public void run() {
securedFlush(); flush();
securedRefresh(); refresh();
for (int i = 0; i < nbIndices; i++) { for (int i = 0; i < nbIndices; i++) {
IndicesStatsResponse indicesStats = client().admin().indices().prepareStats().get(); IndicesStatsResponse indicesStats = client().admin().indices().prepareStats().get();

View File

@ -7,7 +7,6 @@ package org.elasticsearch.xpack.monitoring.resolver.node;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.node.Node; import org.elasticsearch.node.Node;
import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.AggregationBuilders;
@ -87,31 +86,27 @@ public class MultiNodesStatsTests extends MonitoringIntegTestCase {
logger.debug("--> checking that every node correctly reported its own node stats"); logger.debug("--> checking that every node correctly reported its own node stats");
assertBusy(() -> { assertBusy(() -> {
String indices = MONITORING_INDICES_PREFIX + "*"; String indices = MONITORING_INDICES_PREFIX + "*";
securedFlush(indices); flush(indices);
securedRefresh(); refresh();
try { SearchResponse response = client().prepareSearch(indices)
SearchResponse response = client().prepareSearch(indices) .setTypes(NodeStatsResolver.TYPE)
.setTypes(NodeStatsResolver.TYPE) .setSize(0)
.setSize(0) .addAggregation(AggregationBuilders.terms("nodes_ids").field("node_stats.node_id"))
.addAggregation(AggregationBuilders.terms("nodes_ids").field("node_stats.node_id")) .get();
.get();
for (Aggregation aggregation : response.getAggregations()) { for (Aggregation aggregation : response.getAggregations()) {
assertThat(aggregation, instanceOf(StringTerms.class)); assertThat(aggregation, instanceOf(StringTerms.class));
assertThat(((StringTerms) aggregation).getBuckets().size(), equalTo(nbNodes)); assertThat(((StringTerms) aggregation).getBuckets().size(), equalTo(nbNodes));
for (String nodeName : internalCluster().getNodeNames()) { for (String nodeName : internalCluster().getNodeNames()) {
StringTerms.Bucket bucket = ((StringTerms) aggregation) StringTerms.Bucket bucket = ((StringTerms) aggregation)
.getBucketByKey(internalCluster().clusterService(nodeName).localNode().getId()); .getBucketByKey(internalCluster().clusterService(nodeName).localNode().getId());
// At least 1 doc must exist per node, but it can be more than 1 // At least 1 doc must exist per node, but it can be more than 1
// because the first node may have already collected many node stats documents // because the first node may have already collected many node stats documents
// whereas the last node just started to collect node stats. // whereas the last node just started to collect node stats.
assertThat(bucket.getDocCount(), greaterThanOrEqualTo(1L)); assertThat(bucket.getDocCount(), greaterThanOrEqualTo(1L));
}
} }
} catch (IndexNotFoundException e) {
fail("Caught unexpected IndexNotFoundException");
} }
}); });
} }

View File

@ -51,8 +51,8 @@ public class NodeStatsTests extends MonitoringIntegTestCase {
client().prepareIndex("test", "foo").setSource("value", randomInt()).get(); client().prepareIndex("test", "foo").setSource("value", randomInt()).get();
} }
securedFlush(); flush();
securedRefresh(); refresh();
updateMonitoringInterval(3L, TimeUnit.SECONDS); updateMonitoringInterval(3L, TimeUnit.SECONDS);
waitForMonitoringIndices(); waitForMonitoringIndices();

View File

@ -23,7 +23,6 @@ import org.elasticsearch.xpack.monitoring.test.MonitoringIntegTestCase;
import org.junit.After; import org.junit.After;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
@ -63,8 +62,8 @@ public class ShardsTests extends MonitoringIntegTestCase {
client().prepareIndex(INDEX_PREFIX + i, "foo").setRefreshPolicy(IMMEDIATE).setSource("field1", "value1").get(); client().prepareIndex(INDEX_PREFIX + i, "foo").setRefreshPolicy(IMMEDIATE).setSource("field1", "value1").get();
} }
securedFlush(); flush();
securedRefresh(); refresh();
updateMonitoringInterval(3L, TimeUnit.SECONDS); updateMonitoringInterval(3L, TimeUnit.SECONDS);
waitForMonitoringIndices(); waitForMonitoringIndices();

View File

@ -5,12 +5,9 @@
*/ */
package org.elasticsearch.xpack.monitoring.security; package org.elasticsearch.xpack.monitoring.security;
import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.ActionRequestBuilder; import org.elasticsearch.action.ActionRequestBuilder;
import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.xpack.monitoring.MonitoringSettings; import org.elasticsearch.xpack.monitoring.MonitoringSettings;
import org.elasticsearch.xpack.monitoring.test.MonitoringIntegTestCase; import org.elasticsearch.xpack.monitoring.test.MonitoringIntegTestCase;
import org.elasticsearch.xpack.security.InternalClient; import org.elasticsearch.xpack.security.InternalClient;
@ -18,7 +15,6 @@ import org.elasticsearch.xpack.security.InternalClient;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.hamcrest.Matchers.is;
public class MonitoringInternalClientTests extends MonitoringIntegTestCase { public class MonitoringInternalClientTests extends MonitoringIntegTestCase {
@ -60,26 +56,8 @@ public class MonitoringInternalClientTests extends MonitoringIntegTestCase {
assertAccessIsAllowed(internalClient.admin().cluster().prepareGetRepositories()); assertAccessIsAllowed(internalClient.admin().cluster().prepareGetRepositories());
} }
public void assertAccessIsAllowed(ActionRequestBuilder request) { private static void assertAccessIsAllowed(ActionRequestBuilder request) {
try { request.get();
request.get();
} catch (IndexNotFoundException e) {
// Ok
} catch (ElasticsearchSecurityException e) {
fail("unexpected security exception: " + e.getMessage());
}
}
public void assertAccessIsDenied(ActionRequestBuilder request) {
try {
request.get();
fail("expected a security exception");
} catch (IndexNotFoundException e) {
// Ok
} catch (ElasticsearchSecurityException e) {
// expected
assertThat(e.status(), is(RestStatus.FORBIDDEN));
}
} }
/** /**

View File

@ -236,15 +236,7 @@ public abstract class MonitoringIntegTestCase extends ESIntegTestCase {
} }
protected void deleteMonitoringIndices() { protected void deleteMonitoringIndices() {
if (securityEnabled) { assertAcked(client().admin().indices().prepareDelete(MONITORING_INDICES_PREFIX + "*"));
try {
assertAcked(client().admin().indices().prepareDelete(MONITORING_INDICES_PREFIX + "*"));
} catch (IndexNotFoundException e) {
// if security couldn't resolve any monitoring index, it'll throw index not found exception.
}
} else {
assertAcked(client().admin().indices().prepareDelete(MONITORING_INDICES_PREFIX + "*"));
}
} }
protected void awaitMonitoringDocsCount(Matcher<Long> matcher, String... types) throws Exception { protected void awaitMonitoringDocsCount(Matcher<Long> matcher, String... types) throws Exception {
@ -252,31 +244,14 @@ public abstract class MonitoringIntegTestCase extends ESIntegTestCase {
} }
protected void ensureMonitoringIndicesYellow() { protected void ensureMonitoringIndicesYellow() {
if (securityEnabled) { ensureYellow(".monitoring-es-*");
try {
ensureYellow(".monitoring-es-*");
} catch (IndexNotFoundException e) {
// might happen with security...
}
} else {
ensureYellow(".monitoring-es-*");
}
} }
protected void assertMonitoringDocsCount(Matcher<Long> matcher, String... types) { protected void assertMonitoringDocsCount(Matcher<Long> matcher, String... types) {
try { flushAndRefresh(MONITORING_INDICES_PREFIX + "*");
securedFlushAndRefresh(MONITORING_INDICES_PREFIX + "*"); long count = client().prepareSearch(MONITORING_INDICES_PREFIX + "*").setSize(0).setTypes(types).get().getHits().totalHits();
long count = client().prepareSearch(MONITORING_INDICES_PREFIX + "*") logger.trace("--> searched for [{}] documents, found [{}]", Strings.arrayToCommaDelimitedString(types), count);
.setSize(0).setTypes(types).get().getHits().totalHits(); assertThat(count, matcher);
logger.trace("--> searched for [{}] documents, found [{}]", Strings.arrayToCommaDelimitedString(types), count);
assertThat(count, matcher);
} catch (IndexNotFoundException e) {
if (securityEnabled) {
assertThat(0L, matcher);
} else {
throw e;
}
}
} }
protected List<Tuple<String, String>> monitoringTemplates() { protected List<Tuple<String, String>> monitoringTemplates() {
@ -322,16 +297,7 @@ public abstract class MonitoringIntegTestCase extends ESIntegTestCase {
protected void awaitIndexExists(final String index) throws Exception { protected void awaitIndexExists(final String index) throws Exception {
assertBusy(() -> { assertBusy(() -> {
try { assertIndicesExists(index);
assertIndicesExists(index);
} catch (IndexNotFoundException e) {
if (securityEnabled) {
// with security we might get that if wildcards were resolved to no indices
fail("IndexNotFoundException when checking for existence of index [" + index + "]");
} else {
throw e;
}
}
}, 30, TimeUnit.SECONDS); }, 30, TimeUnit.SECONDS);
} }
@ -348,54 +314,6 @@ public abstract class MonitoringIntegTestCase extends ESIntegTestCase {
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(settings)); assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(settings));
} }
protected void securedRefresh() {
if (securityEnabled) {
try {
refresh();
} catch (IndexNotFoundException e) {
// with security we might get that if wildcards were resolved to no indices
}
} else {
refresh();
}
}
protected void securedFlush(String... indices) {
if (securityEnabled) {
try {
flush(indices);
} catch (IndexNotFoundException e) {
// with security we might get that if wildcards were resolved to no indices
}
} else {
flush(indices);
}
}
protected void securedFlushAndRefresh(String... indices) {
if (securityEnabled) {
try {
flushAndRefresh(indices);
} catch (IndexNotFoundException e) {
// with security we might get that if wildcards were resolved to no indices
}
} else {
flushAndRefresh(indices);
}
}
protected void securedEnsureGreen(String... indices) {
if (securityEnabled) {
try {
ensureGreen(indices);
} catch (IndexNotFoundException e) {
// with security we might get that if wildcards were resolved to no indices
}
} else {
ensureGreen(indices);
}
}
/** /**
* Checks if a field exist in a map of values. If the field contains a dot like 'foo.bar' * Checks if a field exist in a map of values. If the field contains a dot like 'foo.bar'
* it checks that 'foo' exists in the map of values and that it points to a sub-map. Then * it checks that 'foo' exists in the map of values and that it points to a sub-map. Then

View File

@ -43,6 +43,8 @@ import org.elasticsearch.action.search.SearchAction;
import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchScrollAction; import org.elasticsearch.action.search.SearchScrollAction;
import org.elasticsearch.action.search.SearchScrollRequest; import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.action.search.SearchTransportService;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.termvectors.TermVectorsAction; import org.elasticsearch.action.termvectors.TermVectorsAction;
import org.elasticsearch.action.termvectors.TermVectorsRequest; import org.elasticsearch.action.termvectors.TermVectorsRequest;
import org.elasticsearch.action.update.UpdateAction; import org.elasticsearch.action.update.UpdateAction;
@ -55,7 +57,6 @@ import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.action.search.SearchTransportService;
import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
@ -65,6 +66,8 @@ import org.elasticsearch.xpack.security.audit.AuditTrailService;
import org.elasticsearch.xpack.security.authc.Authentication; import org.elasticsearch.xpack.security.authc.Authentication;
import org.elasticsearch.xpack.security.authc.Authentication.RealmRef; import org.elasticsearch.xpack.security.authc.Authentication.RealmRef;
import org.elasticsearch.xpack.security.authc.DefaultAuthenticationFailureHandler; import org.elasticsearch.xpack.security.authc.DefaultAuthenticationFailureHandler;
import org.elasticsearch.xpack.security.authz.accesscontrol.IndicesAccessControl;
import org.elasticsearch.xpack.security.authz.indicesresolver.DefaultIndicesAndAliasesResolver;
import org.elasticsearch.xpack.security.authz.permission.Role; import org.elasticsearch.xpack.security.authz.permission.Role;
import org.elasticsearch.xpack.security.authz.permission.SuperuserRole; import org.elasticsearch.xpack.security.authz.permission.SuperuserRole;
import org.elasticsearch.xpack.security.authz.privilege.ClusterPrivilege; import org.elasticsearch.xpack.security.authz.privilege.ClusterPrivilege;
@ -222,6 +225,41 @@ public class AuthorizationServiceTests extends ESTestCase {
} }
} }
public void testSearchAgainstEmptyCluster() {
User user = new User("test user", "a_all");
when(rolesStore.role("a_all")).thenReturn(Role.builder("a_role").add(IndexPrivilege.ALL, "a").build());
ClusterState state = mock(ClusterState.class);
when(clusterService.state()).thenReturn(state);
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
{
//ignore_unavailable set to false, user is not authorized for this index nor does it exist
SearchRequest searchRequest = new SearchRequest("does_not_exist")
.indicesOptions(IndicesOptions.fromOptions(false, true, true, false));
try {
authorizationService.authorize(createAuthentication(user), SearchAction.NAME, searchRequest);
fail("indices request for b should be denied since there is no such index");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [" + SearchAction.NAME + "] is unauthorized for user [test user]"));
verify(auditTrail).accessDenied(user, SearchAction.NAME, searchRequest);
verifyNoMoreInteractions(auditTrail);
}
}
{
//ignore_unavailable and allow_no_indices both set to true, user is not authorized for this index nor does it exist
SearchRequest searchRequest = new SearchRequest("does_not_exist")
.indicesOptions(IndicesOptions.fromOptions(true, true, true, false));
authorizationService.authorize(createAuthentication(user), SearchAction.NAME, searchRequest);
verify(auditTrail).accessGranted(user, SearchAction.NAME, searchRequest);
IndicesAccessControl indicesAccessControl = threadContext.getTransient(AuthorizationService.INDICES_PERMISSIONS_KEY);
IndicesAccessControl.IndexAccessControl indexAccessControl =
indicesAccessControl.getIndexPermissions(DefaultIndicesAndAliasesResolver.NO_INDEX);
assertFalse(indexAccessControl.getFieldPermissions().hasFieldLevelSecurity());
assertNull(indexAccessControl.getQueries());
}
}
public void testScrollRelatedRequestsAllowed() { public void testScrollRelatedRequestsAllowed() {
User user = new User("test user", "a_all"); User user = new User("test user", "a_all");
when(rolesStore.role("a_all")).thenReturn(Role.builder("a_role").add(IndexPrivilege.ALL, "a").build()); when(rolesStore.role("a_all")).thenReturn(Role.builder("a_role").add(IndexPrivilege.ALL, "a").build());

View File

@ -182,15 +182,13 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
assertThat(e.toString(), containsString("[_all]")); assertThat(e.toString(), containsString("[_all]"));
} }
try { GetAliasesResponse getAliasesResponse = client().filterWithHeader(headers).admin().indices().prepareGetAliases("test_alias")
client().filterWithHeader(headers).admin().indices().prepareGetAliases("test_alias").setIndices("test_*") .setIndices("test_*").setIndicesOptions(IndicesOptions.strictExpand()).get();
.setIndicesOptions(IndicesOptions.strictExpand()).get(); assertEquals(0, getAliasesResponse.getAliases().size());
fail("get alias should have failed due to missing manage_aliases privileges");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[test_*]"));
}
try { try {
//this throws exception no matter what the indices options are because the aliases part cannot be resolved to any alias
//and there is no way to "allow_no_aliases" like we can do with indices.
client().filterWithHeader(headers).admin().indices().prepareGetAliases().get(); client().filterWithHeader(headers).admin().indices().prepareGetAliases().get();
fail("get alias should have failed due to missing manage_aliases privileges"); fail("get alias should have failed due to missing manage_aliases privileges");
} catch(IndexNotFoundException e) { } catch(IndexNotFoundException e) {
@ -202,13 +200,10 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
//user has create permission only: allows to create indices, manage_aliases is required to retrieve aliases though //user has create permission only: allows to create indices, manage_aliases is required to retrieve aliases though
Map<String, String> headers = Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("create_only", Map<String, String> headers = Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("create_only",
new SecuredString("test123".toCharArray()))); new SecuredString("test123".toCharArray())));
try {
client().filterWithHeader(headers).admin().indices().prepareGetAliases("test_1").setIndices("test_1") GetAliasesResponse getAliasesResponse = client().filterWithHeader(headers).admin().indices().prepareGetAliases("test_1")
.setIndicesOptions(IndicesOptions.lenientExpandOpen()).get(); .setIndices("test_1").setIndicesOptions(IndicesOptions.lenientExpandOpen()).get();
fail("get alias should have failed due empty set of indices after indices resolution"); assertEquals(0, getAliasesResponse.getAliases().size());
} catch(IndexNotFoundException e) {
assertEquals("no such index", e.getMessage());
}
try { try {
client().filterWithHeader(headers).admin().indices().prepareGetAliases("_all").setIndices("test_1") client().filterWithHeader(headers).admin().indices().prepareGetAliases("_all").setIndices("test_1")
@ -226,15 +221,13 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
assertEquals("no such index", e.getMessage()); assertEquals("no such index", e.getMessage());
} }
try { getAliasesResponse = client().filterWithHeader(headers).admin().indices().prepareGetAliases("test_alias")
client().filterWithHeader(headers).admin().indices().prepareGetAliases("test_alias").setIndices("test_*") .setIndices("test_*").setIndicesOptions(IndicesOptions.lenientExpandOpen()).get();
.setIndicesOptions(IndicesOptions.lenientExpandOpen()).get(); assertEquals(0, getAliasesResponse.getAliases().size());
fail("get alias should have failed due empty set of indices after indices resolution");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[test_*]"));
}
try { try {
//this throws exception no matter what the indices options are because the aliases part cannot be resolved to any alias
//and there is no way to "allow_no_aliases" like we can do with indices.
client().filterWithHeader(headers).admin().indices().prepareGetAliases() client().filterWithHeader(headers).admin().indices().prepareGetAliases()
.setIndicesOptions(IndicesOptions.lenientExpandOpen()).get(); .setIndicesOptions(IndicesOptions.lenientExpandOpen()).get();
fail("get alias should have failed due to missing manage_aliases privileges"); fail("get alias should have failed due to missing manage_aliases privileges");
@ -518,21 +511,14 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
containsString("action [indices:admin/aliases/get] is unauthorized for user [create_test_aliases_alias]")); containsString("action [indices:admin/aliases/get] is unauthorized for user [create_test_aliases_alias]"));
} }
try { //user doesn't have manage_aliases aliases on test_*, no matching indices to replace wildcards
//fails: user doesn't have manage_aliases aliases on test_*, no matching indices to replace wildcards GetAliasesResponse getAliasesResponse = client.admin().indices().prepareGetAliases()
client.admin().indices().prepareGetAliases().setIndices("test_*").setAliases("test_alias").get(); .setIndices("test_*").setAliases("test_alias").get();
fail("get alias should have failed due to missing manage_aliases privileges on test_*"); assertEquals(0, getAliasesResponse.getAliases().size());
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[test_*]"));
}
try { //no existing indices to replace empty indices (thus _all)
//fails: no existing indices to replace empty indices (thus _all) getAliasesResponse = client.admin().indices().prepareGetAliases().setAliases("test_alias").get();
client.admin().indices().prepareGetAliases().setAliases("test_alias").get(); assertEquals(0, getAliasesResponse.getAliases().size());
fail("get alias should have failed due to missing manage_aliases privileges on any index");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[_all]"));
}
try { try {
//fails: no existing aliases to replace wildcards //fails: no existing aliases to replace wildcards
@ -712,31 +698,19 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
//user has manage_aliases only permissions on both alias_* and test_* //user has manage_aliases only permissions on both alias_* and test_*
//ok: manage_aliases on both test_* and alias_* //ok: manage_aliases on both test_* and alias_*
try { GetAliasesResponse getAliasesResponse = client.admin().indices().prepareGetAliases("alias_1")
client.admin().indices().prepareGetAliases("alias_1") .addIndices("test_1").setIndicesOptions(IndicesOptions.lenientExpandOpen()).get();
.addIndices("test_1").setIndicesOptions(IndicesOptions.lenientExpandOpen()).get(); assertEquals(0, getAliasesResponse.getAliases().size());
fail("Expected IndexNotFoundException");
} catch(IndexNotFoundException e) {
assertEquals("no such index", e.getMessage());
}
try { //no manage_aliases privilege on non_authorized alias
//fails: no manage_aliases privilege on non_authorized alias getAliasesResponse = client.admin().indices().prepareGetAliases("non_authorized").addIndices("test_1")
client.admin().indices().prepareGetAliases("non_authorized").addIndices("test_1") .setIndicesOptions(IndicesOptions.lenientExpandOpen()).get();
.setIndicesOptions(IndicesOptions.lenientExpandOpen()).get(); assertEquals(0, getAliasesResponse.getAliases().size());
fail("Expected IndexNotFoundException");
} catch(IndexNotFoundException e) {
assertEquals("no such index", e.getMessage());
}
try { //no manage_aliases privilege on non_authorized index
//fails: no manage_aliases privilege on non_authorized index getAliasesResponse = client.admin().indices().prepareGetAliases("alias_1").addIndices("non_authorized")
client.admin().indices().prepareGetAliases("alias_1").addIndices("non_authorized") .setIndicesOptions(IndicesOptions.lenientExpandOpen()).get();
.setIndicesOptions(IndicesOptions.lenientExpandOpen()).get(); assertEquals(0, getAliasesResponse.getAliases().size());
fail("Expected IndexNotFoundException");
} catch(IndexNotFoundException e) {
assertEquals("no such index", e.getMessage());
}
} }
private static void assertAliases(GetAliasesRequestBuilder getAliasesRequestBuilder, String index, String... aliases) { private static void assertAliases(GetAliasesRequestBuilder getAliasesRequestBuilder, String index, String... aliases) {

View File

@ -6,6 +6,7 @@
package org.elasticsearch.xpack.security.authz.indicesresolver; package org.elasticsearch.xpack.security.authz.indicesresolver;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
@ -110,7 +111,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveEmptyIndicesExpandWilcardsOpenAndClosed() { public void testResolveEmptyIndicesExpandWilcardsOpenAndClosed() {
SearchRequest request = new SearchRequest(); SearchRequest request = new SearchRequest();
request.indicesOptions(IndicesOptions.strictExpand()); request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), true, true));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"bar", "bar-closed", "foofoobar", "foofoo", "foofoo-closed"}; String[] replacedIndices = new String[]{"bar", "bar-closed", "foofoobar", "foofoo", "foofoo-closed"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -121,7 +122,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveEmptyIndicesExpandWilcardsOpen() { public void testResolveEmptyIndicesExpandWilcardsOpen() {
SearchRequest request = new SearchRequest(); SearchRequest request = new SearchRequest();
request.indicesOptions(randomFrom(IndicesOptions.strictExpandOpen(), IndicesOptions.lenientExpandOpen())); request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), true, false));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"bar", "foofoobar", "foofoo"}; String[] replacedIndices = new String[]{"bar", "foofoobar", "foofoo"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -132,7 +133,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveAllExpandWilcardsOpenAndClosed() { public void testResolveAllExpandWilcardsOpenAndClosed() {
SearchRequest request = new SearchRequest("_all"); SearchRequest request = new SearchRequest("_all");
request.indicesOptions(IndicesOptions.strictExpand()); request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), true, true));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"bar", "bar-closed", "foofoobar", "foofoo", "foofoo-closed"}; String[] replacedIndices = new String[]{"bar", "bar-closed", "foofoobar", "foofoo", "foofoo-closed"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -143,7 +144,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveAllExpandWilcardsOpen() { public void testResolveAllExpandWilcardsOpen() {
SearchRequest request = new SearchRequest("_all"); SearchRequest request = new SearchRequest("_all");
request.indicesOptions(randomFrom(IndicesOptions.strictExpandOpen(), IndicesOptions.lenientExpandOpen())); request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), true, false));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"bar", "foofoobar", "foofoo"}; String[] replacedIndices = new String[]{"bar", "foofoobar", "foofoo"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -154,7 +155,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveWildcardsStrictExpand() { public void testResolveWildcardsStrictExpand() {
SearchRequest request = new SearchRequest("barbaz", "foofoo*"); SearchRequest request = new SearchRequest("barbaz", "foofoo*");
request.indicesOptions(IndicesOptions.strictExpand()); request.indicesOptions(IndicesOptions.fromOptions(false, randomBoolean(), true, true));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"barbaz", "foofoobar", "foofoo", "foofoo-closed"}; String[] replacedIndices = new String[]{"barbaz", "foofoobar", "foofoo", "foofoo-closed"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -165,7 +166,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveWildcardsExpandOpenAndClosedIgnoreUnavailable() { public void testResolveWildcardsExpandOpenAndClosedIgnoreUnavailable() {
SearchRequest request = new SearchRequest("barbaz", "foofoo*"); SearchRequest request = new SearchRequest("barbaz", "foofoo*");
request.indicesOptions(IndicesOptions.fromOptions(true, false, true, true)); request.indicesOptions(IndicesOptions.fromOptions(true, randomBoolean(), true, true));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"foofoobar", "foofoo", "foofoo-closed"}; String[] replacedIndices = new String[]{"foofoobar", "foofoo", "foofoo-closed"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -176,7 +177,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveWildcardsStrictExpandOpen() { public void testResolveWildcardsStrictExpandOpen() {
SearchRequest request = new SearchRequest("barbaz", "foofoo*"); SearchRequest request = new SearchRequest("barbaz", "foofoo*");
request.indicesOptions(IndicesOptions.strictExpandOpen()); request.indicesOptions(IndicesOptions.fromOptions(false, randomBoolean(), true, false));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"barbaz", "foofoobar", "foofoo"}; String[] replacedIndices = new String[]{"barbaz", "foofoobar", "foofoo"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -187,7 +188,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveWildcardsLenientExpandOpen() { public void testResolveWildcardsLenientExpandOpen() {
SearchRequest request = new SearchRequest("barbaz", "foofoo*"); SearchRequest request = new SearchRequest("barbaz", "foofoo*");
request.indicesOptions(IndicesOptions.lenientExpandOpen()); request.indicesOptions(IndicesOptions.fromOptions(true, randomBoolean(), true, false));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"foofoobar", "foofoo"}; String[] replacedIndices = new String[]{"foofoobar", "foofoo"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -198,7 +199,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveWildcardsMinusExpandWilcardsOpen() { public void testResolveWildcardsMinusExpandWilcardsOpen() {
SearchRequest request = new SearchRequest("-foofoo*"); SearchRequest request = new SearchRequest("-foofoo*");
request.indicesOptions(randomFrom(IndicesOptions.strictExpandOpen(), IndicesOptions.lenientExpandOpen())); request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), true, false));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"bar"}; String[] replacedIndices = new String[]{"bar"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -209,7 +210,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveWildcardsMinusExpandWilcardsOpenAndClosed() { public void testResolveWildcardsMinusExpandWilcardsOpenAndClosed() {
SearchRequest request = new SearchRequest("-foofoo*"); SearchRequest request = new SearchRequest("-foofoo*");
request.indicesOptions(IndicesOptions.strictExpand()); request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), true, true));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"bar", "bar-closed"}; String[] replacedIndices = new String[]{"bar", "bar-closed"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -220,9 +221,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveWildcardsPlusAndMinusExpandWilcardsOpenStrict() { public void testResolveWildcardsPlusAndMinusExpandWilcardsOpenStrict() {
SearchRequest request = new SearchRequest("-foofoo*", "+barbaz", "+foob*"); SearchRequest request = new SearchRequest("-foofoo*", "+barbaz", "+foob*");
if (randomBoolean()) { request.indicesOptions(IndicesOptions.fromOptions(false, true, true, false));
request.indicesOptions(IndicesOptions.strictExpandOpen());
}
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"bar", "barbaz"}; String[] replacedIndices = new String[]{"bar", "barbaz"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -233,7 +232,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveWildcardsPlusAndMinusExpandWilcardsOpenIgnoreUnavailable() { public void testResolveWildcardsPlusAndMinusExpandWilcardsOpenIgnoreUnavailable() {
SearchRequest request = new SearchRequest("-foofoo*", "+barbaz", "+foob*"); SearchRequest request = new SearchRequest("-foofoo*", "+barbaz", "+foob*");
request.indicesOptions(IndicesOptions.lenientExpandOpen()); request.indicesOptions(IndicesOptions.fromOptions(true, true, true, false));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"bar"}; String[] replacedIndices = new String[]{"bar"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -244,7 +243,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveWildcardsPlusAndMinusExpandWilcardsOpenAndClosedStrict() { public void testResolveWildcardsPlusAndMinusExpandWilcardsOpenAndClosedStrict() {
SearchRequest request = new SearchRequest("-foofoo*", "+barbaz"); SearchRequest request = new SearchRequest("-foofoo*", "+barbaz");
request.indicesOptions(IndicesOptions.strictExpand()); request.indicesOptions(IndicesOptions.fromOptions(false, randomBoolean(), true, true));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"bar", "bar-closed", "barbaz"}; String[] replacedIndices = new String[]{"bar", "bar-closed", "barbaz"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -255,7 +254,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveWildcardsPlusAndMinusExpandWilcardsOpenAndClosedIgnoreUnavailable() { public void testResolveWildcardsPlusAndMinusExpandWilcardsOpenAndClosedIgnoreUnavailable() {
SearchRequest request = new SearchRequest("-foofoo*", "+barbaz"); SearchRequest request = new SearchRequest("-foofoo*", "+barbaz");
request.indicesOptions(IndicesOptions.fromOptions(true, false, true, true)); request.indicesOptions(IndicesOptions.fromOptions(true, randomBoolean(), true, true));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"bar", "bar-closed"}; String[] replacedIndices = new String[]{"bar", "bar-closed"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -264,21 +263,23 @@ public class DefaultIndicesResolverTests extends ESTestCase {
assertThat(request.indices(), arrayContainingInAnyOrder(replacedIndices)); assertThat(request.indices(), arrayContainingInAnyOrder(replacedIndices));
} }
public void testResolveNonMatchingIndices() { public void testResolveNonMatchingIndicesAllowNoIndices() {
SearchRequest request = new SearchRequest("missing*"); SearchRequest request = new SearchRequest("missing*");
try { request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), true, true, randomBoolean()));
defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); assertNoIndices(request, defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData));
fail("Expected IndexNotFoundException"); }
} catch (IndexNotFoundException e) {
assertThat(e.getMessage(), is("no such index")); public void testResolveNonMatchingIndicesDisallowNoIndices() {
} SearchRequest request = new SearchRequest("missing*");
request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), false, true, randomBoolean()));
IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
() -> defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData));
assertEquals("no such index", e.getMessage());
} }
public void testResolveExplicitIndicesStrict() { public void testResolveExplicitIndicesStrict() {
SearchRequest request = new SearchRequest("missing", "bar", "barbaz"); SearchRequest request = new SearchRequest("missing", "bar", "barbaz");
if (randomBoolean()) { request.indicesOptions(IndicesOptions.fromOptions(false, randomBoolean(), randomBoolean(), randomBoolean()));
request.indicesOptions(IndicesOptions.strictExpandOpenAndForbidClosed());
}
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"missing", "bar", "barbaz"}; String[] replacedIndices = new String[]{"missing", "bar", "barbaz"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -289,7 +290,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveExplicitIndicesIgnoreUnavailable() { public void testResolveExplicitIndicesIgnoreUnavailable() {
SearchRequest request = new SearchRequest("missing", "bar", "barbaz"); SearchRequest request = new SearchRequest("missing", "bar", "barbaz");
request.indicesOptions(IndicesOptions.lenientExpandOpen()); request.indicesOptions(IndicesOptions.fromOptions(true, randomBoolean(), randomBoolean(), randomBoolean()));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] replacedIndices = new String[]{"bar"}; String[] replacedIndices = new String[]{"bar"};
assertThat(indices.size(), equalTo(replacedIndices.length)); assertThat(indices.size(), equalTo(replacedIndices.length));
@ -298,21 +299,23 @@ public class DefaultIndicesResolverTests extends ESTestCase {
assertThat(request.indices(), arrayContainingInAnyOrder(replacedIndices)); assertThat(request.indices(), arrayContainingInAnyOrder(replacedIndices));
} }
public void testResolveNoAuthorizedIndices() { public void testResolveNoAuthorizedIndicesAllowNoIndices() {
SearchRequest request = new SearchRequest(); SearchRequest request = new SearchRequest();
if (randomBoolean()) { request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), true, true, randomBoolean()));
request.indicesOptions(IndicesOptions.lenientExpandOpen()); assertNoIndices(request, defaultIndicesResolver.resolve(userNoIndices, SearchAction.NAME, request, metaData));
} }
try {
defaultIndicesResolver.resolve(userNoIndices, SearchAction.NAME, request, metaData); public void testResolveNoAuthorizedIndicesDisallowNoIndices() {
fail("Expected IndexNotFoundException"); SearchRequest request = new SearchRequest();
} catch (IndexNotFoundException e) { request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), false, true, randomBoolean()));
assertThat(e.getMessage(), is("no such index")); IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
} () -> defaultIndicesResolver.resolve(userNoIndices, SearchAction.NAME, request, metaData));
assertEquals("no such index", e.getMessage());
} }
public void testResolveMissingIndexStrict() { public void testResolveMissingIndexStrict() {
SearchRequest request = new SearchRequest("bar*", "missing"); SearchRequest request = new SearchRequest("bar*", "missing");
request.indicesOptions(IndicesOptions.fromOptions(false, true, true, false));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] expectedIndices = new String[]{"bar", "missing"}; String[] expectedIndices = new String[]{"bar", "missing"};
assertThat(indices.size(), equalTo(expectedIndices.length)); assertThat(indices.size(), equalTo(expectedIndices.length));
@ -323,7 +326,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveMissingIndexIgnoreUnavailable() { public void testResolveMissingIndexIgnoreUnavailable() {
SearchRequest request = new SearchRequest("bar*", "missing"); SearchRequest request = new SearchRequest("bar*", "missing");
request.indicesOptions(IndicesOptions.lenientExpandOpen()); request.indicesOptions(IndicesOptions.fromOptions(true, randomBoolean(), true, false));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] expectedIndices = new String[]{"bar"}; String[] expectedIndices = new String[]{"bar"};
assertThat(indices.size(), equalTo(expectedIndices.length)); assertThat(indices.size(), equalTo(expectedIndices.length));
@ -334,24 +337,28 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveNonMatchingIndicesAndExplicit() { public void testResolveNonMatchingIndicesAndExplicit() {
SearchRequest request = new SearchRequest("missing*", "bar"); SearchRequest request = new SearchRequest("missing*", "bar");
if (randomBoolean()) { request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), true, true, randomBoolean()));
request.indicesOptions(randomFrom(IndicesOptions.lenientExpandOpen(), IndicesOptions.strictExpandOpen()));
}
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] expectedIndices = new String[]{"bar"}; String[] expectedIndices = new String[]{"bar"};
assertThat(indices.toArray(new String[indices.size()]), equalTo(expectedIndices)); assertThat(indices.toArray(new String[indices.size()]), equalTo(expectedIndices));
assertThat(request.indices(), equalTo(expectedIndices)); assertThat(request.indices(), equalTo(expectedIndices));
} }
public void testResolveNoExpand() { public void testResolveNoExpandStrict() {
SearchRequest request = new SearchRequest("missing*"); SearchRequest request = new SearchRequest("missing*");
request.indicesOptions(IndicesOptions.strictSingleIndexNoExpandForbidClosed()); request.indicesOptions(IndicesOptions.fromOptions(false, randomBoolean(), false, false));
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
String[] expectedIndices = new String[]{"missing*"}; String[] expectedIndices = new String[]{"missing*"};
assertThat(indices.toArray(new String[indices.size()]), equalTo(expectedIndices)); assertThat(indices.toArray(new String[indices.size()]), equalTo(expectedIndices));
assertThat(request.indices(), equalTo(expectedIndices)); assertThat(request.indices(), equalTo(expectedIndices));
} }
public void testResolveNoExpandIgnoreUnavailable() {
SearchRequest request = new SearchRequest("missing*");
request.indicesOptions(IndicesOptions.fromOptions(true, true, false, false));
assertNoIndices(request, defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData));
}
public void testResolveIndicesAliasesRequest() { public void testResolveIndicesAliasesRequest() {
IndicesAliasesRequest request = new IndicesAliasesRequest(); IndicesAliasesRequest request = new IndicesAliasesRequest();
request.addAliasAction(AliasActions.add().alias("alias1").indices("foo", "foofoo")); request.addAliasAction(AliasActions.add().alias("alias1").indices("foo", "foofoo"));
@ -581,9 +588,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveGetAliasesRequestStrict() { public void testResolveGetAliasesRequestStrict() {
GetAliasesRequest request = new GetAliasesRequest("alias1").indices("foo", "foofoo"); GetAliasesRequest request = new GetAliasesRequest("alias1").indices("foo", "foofoo");
if (randomBoolean()) { request.indicesOptions(IndicesOptions.fromOptions(false, randomBoolean(), randomBoolean(), randomBoolean()));
request.indicesOptions(randomFrom(IndicesOptions.strictExpand(), IndicesOptions.strictExpandOpen()));
}
Set<String> indices = defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData);
//the union of all indices and aliases gets returned //the union of all indices and aliases gets returned
String[] expectedIndices = new String[]{"alias1", "foo", "foofoo"}; String[] expectedIndices = new String[]{"alias1", "foo", "foofoo"};
@ -595,7 +600,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveGetAliasesRequestIgnoreUnavailable() { public void testResolveGetAliasesRequestIgnoreUnavailable() {
GetAliasesRequest request = new GetAliasesRequest("alias1").indices("foo", "foofoo"); GetAliasesRequest request = new GetAliasesRequest("alias1").indices("foo", "foofoo");
request.indicesOptions(IndicesOptions.lenientExpandOpen()); request.indicesOptions(IndicesOptions.fromOptions(true, randomBoolean(), randomBoolean(), randomBoolean()));
Set<String> indices = defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData);
String[] expectedIndices = new String[]{"alias1", "foofoo"}; String[] expectedIndices = new String[]{"alias1", "foofoo"};
assertThat(indices.size(), equalTo(expectedIndices.length)); assertThat(indices.size(), equalTo(expectedIndices.length));
@ -606,9 +611,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveGetAliasesRequestMissingIndexStrict() { public void testResolveGetAliasesRequestMissingIndexStrict() {
GetAliasesRequest request = new GetAliasesRequest(); GetAliasesRequest request = new GetAliasesRequest();
if (randomBoolean()) { request.indicesOptions(IndicesOptions.fromOptions(false, randomBoolean(), true, randomBoolean()));
request.indicesOptions(randomFrom(IndicesOptions.strictExpandOpen(), IndicesOptions.strictExpand()));
}
request.indices("missing"); request.indices("missing");
request.aliases("alias2"); request.aliases("alias2");
Set<String> indices = defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData);
@ -620,9 +623,9 @@ public class DefaultIndicesResolverTests extends ESTestCase {
assertThat(request.aliases(), arrayContainingInAnyOrder("alias2")); assertThat(request.aliases(), arrayContainingInAnyOrder("alias2"));
} }
public void testResolveGetAliasesRequestMissingIndexIgnoreUnavailable() { public void testGetAliasesRequestMissingIndexIgnoreUnavailableDisallowNoIndices() {
GetAliasesRequest request = new GetAliasesRequest(); GetAliasesRequest request = new GetAliasesRequest();
request.indicesOptions(IndicesOptions.lenientExpandOpen()); request.indicesOptions(IndicesOptions.fromOptions(true, false, randomBoolean(), randomBoolean()));
request.indices("missing"); request.indices("missing");
request.aliases("alias2"); request.aliases("alias2");
IndexNotFoundException exception = expectThrows(IndexNotFoundException.class, IndexNotFoundException exception = expectThrows(IndexNotFoundException.class,
@ -630,11 +633,30 @@ public class DefaultIndicesResolverTests extends ESTestCase {
assertEquals("no such index", exception.getMessage()); assertEquals("no such index", exception.getMessage());
} }
public void testGetAliasesRequestMissingIndexIgnoreUnavailableAllowNoIndices() {
GetAliasesRequest request = new GetAliasesRequest();
request.indicesOptions(IndicesOptions.fromOptions(true, true, randomBoolean(), randomBoolean()));
request.indices("missing");
request.aliases("alias2");
assertNoIndices(request, defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData));
}
public void testGetAliasesRequestMissingIndexStrict() {
GetAliasesRequest request = new GetAliasesRequest();
request.indicesOptions(IndicesOptions.fromOptions(false, randomBoolean(), randomBoolean(), randomBoolean()));
request.indices("missing");
request.aliases("alias2");
Set<String> indices = defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData);
String[] expectedIndices = new String[]{"alias2", "missing"};
assertThat(indices.size(), equalTo(expectedIndices.length));
assertThat(indices, hasItems(expectedIndices));
assertThat(request.indices(), arrayContainingInAnyOrder("missing"));
assertThat(request.aliases(), arrayContainingInAnyOrder("alias2"));
}
public void testResolveWildcardsGetAliasesRequestStrictExpand() { public void testResolveWildcardsGetAliasesRequestStrictExpand() {
GetAliasesRequest request = new GetAliasesRequest(); GetAliasesRequest request = new GetAliasesRequest();
if (randomBoolean()) { request.indicesOptions(IndicesOptions.fromOptions(false, randomBoolean(), true, true));
request.indicesOptions(IndicesOptions.strictExpand());
}
request.aliases("alias1"); request.aliases("alias1");
request.indices("foo*"); request.indices("foo*");
Set<String> indices = defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData);
@ -649,7 +671,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveWildcardsGetAliasesRequestStrictExpandOpen() { public void testResolveWildcardsGetAliasesRequestStrictExpandOpen() {
GetAliasesRequest request = new GetAliasesRequest(); GetAliasesRequest request = new GetAliasesRequest();
request.indicesOptions(IndicesOptions.strictExpandOpen()); request.indicesOptions(IndicesOptions.fromOptions(false, randomBoolean(), true, false));
request.aliases("alias1"); request.aliases("alias1");
request.indices("foo*"); request.indices("foo*");
Set<String> indices = defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData);
@ -664,7 +686,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
public void testResolveWildcardsGetAliasesRequestLenientExpandOpen() { public void testResolveWildcardsGetAliasesRequestLenientExpandOpen() {
GetAliasesRequest request = new GetAliasesRequest(); GetAliasesRequest request = new GetAliasesRequest();
request.indicesOptions(IndicesOptions.lenientExpandOpen()); request.indicesOptions(IndicesOptions.fromOptions(true, randomBoolean(), true, false));
request.aliases("alias1"); request.aliases("alias1");
request.indices("foo*", "bar", "missing"); request.indices("foo*", "bar", "missing");
Set<String> indices = defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData);
@ -677,17 +699,22 @@ public class DefaultIndicesResolverTests extends ESTestCase {
assertThat(request.aliases(), arrayContainingInAnyOrder("alias1")); assertThat(request.aliases(), arrayContainingInAnyOrder("alias1"));
} }
public void testResolveWildcardsGetAliasesRequestNoMatchingIndices() { public void testWildcardsGetAliasesRequestNoMatchingIndicesDisallowNoIndices() {
GetAliasesRequest request = new GetAliasesRequest(); GetAliasesRequest request = new GetAliasesRequest();
request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), false, true, randomBoolean()));
request.aliases("alias3"); request.aliases("alias3");
request.indices("non_matching_*"); request.indices("non_matching_*");
//indices get resolved to no indices, request gets rejected IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
try { () -> defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData));
defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData); assertEquals("no such index", e.getMessage());
fail("Expected IndexNotFoundException"); }
} catch (IndexNotFoundException e) {
assertThat(e.getMessage(), is("no such index")); public void testWildcardsGetAliasesRequestNoMatchingIndicesAllowNoIndices() {
} GetAliasesRequest request = new GetAliasesRequest();
request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), true, true, randomBoolean()));
request.aliases("alias3");
request.indices("non_matching_*");
assertNoIndices(request, defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData));
} }
public void testResolveAllGetAliasesRequest() { public void testResolveAllGetAliasesRequest() {
@ -728,30 +755,41 @@ public class DefaultIndicesResolverTests extends ESTestCase {
assertThat(request.aliases(), arrayContainingInAnyOrder("alias1")); assertThat(request.aliases(), arrayContainingInAnyOrder("alias1"));
} }
public void testResolveAllGetAliasesRequestNoAuthorizedIndices() { public void testAllGetAliasesRequestNoAuthorizedIndicesAllowNoIndices() {
GetAliasesRequest request = new GetAliasesRequest(); GetAliasesRequest request = new GetAliasesRequest();
request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), true, true, randomBoolean()));
request.aliases("alias1"); request.aliases("alias1");
request.indices("_all"); request.indices("_all");
//current user is not authorized for any index, _all resolves to no indices, the request fails assertNoIndices(request, defaultIndicesResolver.resolve(userNoIndices, GetAliasesAction.NAME, request, metaData));
try {
defaultIndicesResolver.resolve(userNoIndices, GetAliasesAction.NAME, request, metaData);
fail("Expected IndexNotFoundException");
} catch (IndexNotFoundException e) {
assertThat(e.getMessage(), is("no such index"));
}
} }
public void testResolveWildcardsGetAliasesRequestNoAuthorizedIndices() { public void testAllGetAliasesRequestNoAuthorizedIndicesDisallowNoIndices() {
GetAliasesRequest request = new GetAliasesRequest();
request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), false, true, randomBoolean()));
request.aliases("alias1");
request.indices("_all");
IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
() -> defaultIndicesResolver.resolve(userNoIndices, GetAliasesAction.NAME, request, metaData));
assertEquals("no such index", e.getMessage());
}
public void testWildcardsGetAliasesRequestNoAuthorizedIndicesAllowNoIndices() {
GetAliasesRequest request = new GetAliasesRequest(); GetAliasesRequest request = new GetAliasesRequest();
request.aliases("alias1"); request.aliases("alias1");
request.indices("foo*"); request.indices("foo*");
request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), true, true, randomBoolean()));
assertNoIndices(request, defaultIndicesResolver.resolve(userNoIndices, GetAliasesAction.NAME, request, metaData));
}
public void testWildcardsGetAliasesRequestNoAuthorizedIndicesDisallowNoIndices() {
GetAliasesRequest request = new GetAliasesRequest();
request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), false, true, randomBoolean()));
request.aliases("alias1");
request.indices("foo*");
//current user is not authorized for any index, foo* resolves to no indices, the request fails //current user is not authorized for any index, foo* resolves to no indices, the request fails
try { IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
defaultIndicesResolver.resolve(userNoIndices, GetAliasesAction.NAME, request, metaData); () -> defaultIndicesResolver.resolve(userNoIndices, GetAliasesAction.NAME, request, metaData));
fail("Expected IndexNotFoundException"); assertEquals("no such index", e.getMessage());
} catch (IndexNotFoundException e) {
assertThat(e.getMessage(), is("no such index"));
}
} }
public void testResolveAllAliasesGetAliasesRequest() { public void testResolveAllAliasesGetAliasesRequest() {
@ -823,12 +861,9 @@ public class DefaultIndicesResolverTests extends ESTestCase {
//no authorized aliases match bar*, hence the request fails //no authorized aliases match bar*, hence the request fails
request.aliases("bar*"); request.aliases("bar*");
request.indices("*bar"); request.indices("*bar");
try { IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData); () -> defaultIndicesResolver.resolve(user, GetAliasesAction.NAME, request, metaData));
fail("Expected IndexNotFoundException"); assertEquals("no such index", e.getMessage());
} catch (IndexNotFoundException e) {
assertThat(e.getMessage(), is("no such index"));
}
} }
public void testResolveAliasesAllGetAliasesRequestNoAuthorizedIndices() { public void testResolveAliasesAllGetAliasesRequestNoAuthorizedIndices() {
@ -838,15 +873,13 @@ public class DefaultIndicesResolverTests extends ESTestCase {
} }
request.indices("non_existing"); request.indices("non_existing");
//current user is not authorized for any index, foo* resolves to no indices, the request fails //current user is not authorized for any index, foo* resolves to no indices, the request fails
try { IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
defaultIndicesResolver.resolve(userNoIndices, GetAliasesAction.NAME, request, metaData); () -> defaultIndicesResolver.resolve(userNoIndices, GetAliasesAction.NAME, request, metaData));
fail("Expected IndexNotFoundException"); assertEquals("no such index", e.getMessage());
} catch (IndexNotFoundException e) {
assertThat(e.getMessage(), is("no such index"));
}
} }
//msearch is a CompositeIndicesRequest whose items (SearchRequests) implement IndicesRequest.Replaceable, wildcards will get replaced //msearch is a CompositeIndicesRequest whose items (SearchRequests) implement IndicesRequest.Replaceable, wildcards will get replaced
@AwaitsFix(bugUrl = "multi requests endpoints need fixing, we shouldn't merge all the indices in one collection")
public void testResolveMultiSearchNoWildcards() { public void testResolveMultiSearchNoWildcards() {
MultiSearchRequest request = new MultiSearchRequest(); MultiSearchRequest request = new MultiSearchRequest();
request.add(Requests.searchRequest("foo", "bar")); request.add(Requests.searchRequest("foo", "bar"));
@ -859,6 +892,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
assertThat(request.subRequests().get(1).indices(), equalTo(new String[]{"bar2"})); assertThat(request.subRequests().get(1).indices(), equalTo(new String[]{"bar2"}));
} }
@AwaitsFix(bugUrl = "multi requests endpoints need fixing, we shouldn't merge all the indices in one collection")
public void testResolveMultiSearchNoWildcardsMissingIndex() { public void testResolveMultiSearchNoWildcardsMissingIndex() {
MultiSearchRequest request = new MultiSearchRequest(); MultiSearchRequest request = new MultiSearchRequest();
request.add(Requests.searchRequest("foo", "bar")); request.add(Requests.searchRequest("foo", "bar"));
@ -873,6 +907,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
assertThat(request.subRequests().get(2).indices(), equalTo(new String[]{"missing"})); assertThat(request.subRequests().get(2).indices(), equalTo(new String[]{"missing"}));
} }
@AwaitsFix(bugUrl = "multi requests endpoints need fixing, we shouldn't merge all the indices in one collection")
public void testResolveMultiSearchWildcardsExpandOpen() { public void testResolveMultiSearchWildcardsExpandOpen() {
MultiSearchRequest request = new MultiSearchRequest(); MultiSearchRequest request = new MultiSearchRequest();
request.add(Requests.searchRequest("bar*")).indicesOptions( request.add(Requests.searchRequest("bar*")).indicesOptions(
@ -886,6 +921,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
assertThat(request.subRequests().get(1).indices(), equalTo(new String[]{"foobar"})); assertThat(request.subRequests().get(1).indices(), equalTo(new String[]{"foobar"}));
} }
@AwaitsFix(bugUrl = "multi requests endpoints need fixing, we shouldn't merge all the indices in one collection")
public void testResolveMultiSearchWildcardsExpandOpenAndClose() { public void testResolveMultiSearchWildcardsExpandOpenAndClose() {
MultiSearchRequest request = new MultiSearchRequest(); MultiSearchRequest request = new MultiSearchRequest();
request.add(Requests.searchRequest("bar*").indicesOptions(IndicesOptions.strictExpand())); request.add(Requests.searchRequest("bar*").indicesOptions(IndicesOptions.strictExpand()));
@ -898,6 +934,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
assertThat(request.subRequests().get(1).indices(), equalTo(new String[]{"foobar"})); assertThat(request.subRequests().get(1).indices(), equalTo(new String[]{"foobar"}));
} }
@AwaitsFix(bugUrl = "multi requests endpoints need fixing, we shouldn't merge all the indices in one collection")
public void testResolveMultiSearchWildcardsMissingIndex() { public void testResolveMultiSearchWildcardsMissingIndex() {
MultiSearchRequest request = new MultiSearchRequest(); MultiSearchRequest request = new MultiSearchRequest();
request.add(Requests.searchRequest("bar*")); request.add(Requests.searchRequest("bar*"));
@ -910,6 +947,7 @@ public class DefaultIndicesResolverTests extends ESTestCase {
assertThat(request.subRequests().get(1).indices(), equalTo(new String[]{"missing"})); assertThat(request.subRequests().get(1).indices(), equalTo(new String[]{"missing"}));
} }
@AwaitsFix(bugUrl = "multi requests endpoints need fixing, we shouldn't merge all the indices in one collection")
public void testResolveMultiSearchWildcardsNoMatchingIndices() { public void testResolveMultiSearchWildcardsNoMatchingIndices() {
MultiSearchRequest request = new MultiSearchRequest(); MultiSearchRequest request = new MultiSearchRequest();
request.add(Requests.searchRequest("missing*")); request.add(Requests.searchRequest("missing*"));
@ -922,6 +960,20 @@ public class DefaultIndicesResolverTests extends ESTestCase {
} }
} }
@AwaitsFix(bugUrl = "multi requests endpoints need fixing, we shouldn't merge all the indices in one collection")
public void testMultiSearchWildcardsNoAuthorizedIndices() {
MultiSearchRequest request = new MultiSearchRequest();
request.add(Requests.searchRequest("foofoo*"));
request.add(Requests.searchRequest("foobar"));
try {
defaultIndicesResolver.resolve(userNoIndices, MultiSearchAction.NAME, request, metaData);
fail("Expected IndexNotFoundException");
} catch (IndexNotFoundException e) {
assertThat(e.getMessage(), is("no such index"));
}
}
@AwaitsFix(bugUrl = "multi requests endpoints need fixing, we shouldn't merge all the indices in one collection")
public void testResolveMultiSearchWildcardsNoAuthorizedIndices() { public void testResolveMultiSearchWildcardsNoAuthorizedIndices() {
MultiSearchRequest request = new MultiSearchRequest(); MultiSearchRequest request = new MultiSearchRequest();
request.add(Requests.searchRequest("foofoo*")); request.add(Requests.searchRequest("foofoo*"));
@ -994,37 +1046,63 @@ public class DefaultIndicesResolverTests extends ESTestCase {
assertThat(indices, not(hasItem(SecurityTemplateService.SECURITY_INDEX_NAME))); assertThat(indices, not(hasItem(SecurityTemplateService.SECURITY_INDEX_NAME)));
} }
public void testResolvingDateExpression() { public void testUnauthorizedDateMathExpressionIgnoreUnavailable() {
// the user isn't authorized so resolution should fail
SearchRequest request = new SearchRequest("<datetime-{now/M}>"); SearchRequest request = new SearchRequest("<datetime-{now/M}>");
if (randomBoolean()) { request.indicesOptions(IndicesOptions.fromOptions(true, true, randomBoolean(), randomBoolean()));
request.indicesOptions(IndicesOptions.strictSingleIndexNoExpandForbidClosed()); assertNoIndices(request, defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData));
} }
try {
defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
fail("user is not authorized to see this index");
} catch (IndexNotFoundException e) {
assertThat(e.getMessage(), is("no such index"));
}
public void testUnauthorizedDateMathExpressionIgnoreUnavailableDisallowNoIndices() {
SearchRequest request = new SearchRequest("<datetime-{now/M}>");
request.indicesOptions(IndicesOptions.fromOptions(true, false, randomBoolean(), randomBoolean()));
IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
() -> defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData));
assertEquals("no such index" , e.getMessage());
}
public void testUnauthorizedDateMathExpressionStrict() {
SearchRequest request = new SearchRequest("<datetime-{now/M}>");
request.indicesOptions(IndicesOptions.fromOptions(false, randomBoolean(), randomBoolean(), randomBoolean()));
IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
() -> defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData));
assertEquals("no such index" , e.getMessage());
}
public void testResolveDateMathExpression() {
// make the user authorized // make the user authorized
String[] authorizedIndices = new String[] { "bar", "bar-closed", "foofoobar", "foofoo", "missing", "foofoo-closed", String dateTimeIndex = indexNameExpressionResolver.resolveDateMathExpression("<datetime-{now/M}>");
indexNameExpressionResolver.resolveDateMathExpression("<datetime-{now/M}>")}; String[] authorizedIndices = new String[] { "bar", "bar-closed", "foofoobar", "foofoo", "missing", "foofoo-closed", dateTimeIndex};
when(rolesStore.role("role")).thenReturn(Role.builder("role").add(IndexPrivilege.ALL, authorizedIndices).build()); when(rolesStore.role("role")).thenReturn(Role.builder("role").add(IndexPrivilege.ALL, authorizedIndices).build());
SearchRequest request = new SearchRequest("<datetime-{now/M}>");
if (randomBoolean()) {
request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean()));
}
Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); Set<String> indices = defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData);
assertThat(indices.size(), equalTo(1)); assertThat(indices.size(), equalTo(1));
assertThat(request.indices()[0], equalTo(indexNameExpressionResolver.resolveDateMathExpression("<datetime-{now/M}>"))); assertThat(request.indices()[0], equalTo(indexNameExpressionResolver.resolveDateMathExpression("<datetime-{now/M}>")));
} }
public void testMissingDateExpression() { public void testMissingDateMathExpressionIgnoreUnavailable() {
SearchRequest request = new SearchRequest("<foobar-{now/M}>"); SearchRequest request = new SearchRequest("<foobar-{now/M}>");
try { request.indicesOptions(IndicesOptions.fromOptions(true, true, randomBoolean(), randomBoolean()));
defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData); assertNoIndices(request, defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData));
fail("index should not exist"); }
} catch (IndexNotFoundException e) {
assertThat(e.getMessage(), is("no such index")); public void testMissingDateMathExpressionIgnoreUnavailableDisallowNoIndices() {
} SearchRequest request = new SearchRequest("<foobar-{now/M}>");
request.indicesOptions(IndicesOptions.fromOptions(true, false, randomBoolean(), randomBoolean()));
IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
() -> defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData));
assertEquals("no such index" , e.getMessage());
}
public void testMissingDateMathExpressionStrict() {
SearchRequest request = new SearchRequest("<foobar-{now/M}>");
request.indicesOptions(IndicesOptions.fromOptions(false, randomBoolean(), randomBoolean(), randomBoolean()));
IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
() -> defaultIndicesResolver.resolve(user, SearchAction.NAME, request, metaData));
assertEquals("no such index" , e.getMessage());
} }
public void testAliasDateMathExpressionNotSupported() { public void testAliasDateMathExpressionNotSupported() {
@ -1077,4 +1155,11 @@ public class DefaultIndicesResolverTests extends ESTestCase {
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0));
} }
private static void assertNoIndices(IndicesRequest.Replaceable request, Set<String> resolvedIndices) {
assertEquals(1, resolvedIndices.size());
assertEquals(DefaultIndicesAndAliasesResolver.NO_INDEX, resolvedIndices.iterator().next());
assertEquals(1, request.indices().length);
assertEquals(DefaultIndicesAndAliasesResolver.NO_INDEX, request.indices()[0]);
}
} }

View File

@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.elasticsearch.test.SecurityTestsUtils.assertAuthorizationException; import static org.elasticsearch.test.SecurityTestsUtils.assertAuthorizationException;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoSearchHits;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasItems;
@ -57,29 +58,59 @@ public class IndicesAndAliasesResolverIntegrationTests extends SecurityIntegTest
public void testSearchNonAuthorizedWildcard() { public void testSearchNonAuthorizedWildcard() {
//wildcard doesn't match any authorized index //wildcard doesn't match any authorized index
createIndices("test1", "test2", "index1", "index2"); createIndices("test1", "test2", "index1", "index2");
IndexNotFoundException e = expectThrows(IndexNotFoundException.class, () -> client().prepareSearch("index*").get()); assertNoSearchHits(client().prepareSearch("index*").get());
}
public void testSearchNonAuthorizedWildcardDisallowNoIndices() {
//wildcard doesn't match any authorized index
createIndices("test1", "test2", "index1", "index2");
IndexNotFoundException e = expectThrows(IndexNotFoundException.class, () -> client().prepareSearch("index*")
.setIndicesOptions(IndicesOptions.fromOptions(randomBoolean(), false, true, randomBoolean())).get());
assertEquals("no such index", e.getMessage()); assertEquals("no such index", e.getMessage());
} }
public void testEmptyClusterSearchForAll() { public void testEmptyClusterSearchForAll() {
IndexNotFoundException e = expectThrows(IndexNotFoundException.class, () -> client().prepareSearch().get()); assertNoSearchHits(client().prepareSearch().get());
}
public void testEmptyClusterSearchForAllDisallowNoIndices() {
IndexNotFoundException e = expectThrows(IndexNotFoundException.class, () -> client().prepareSearch()
.setIndicesOptions(IndicesOptions.fromOptions(randomBoolean(), false, true, randomBoolean())).get());
assertEquals("no such index", e.getMessage()); assertEquals("no such index", e.getMessage());
} }
public void testEmptyClusterSearchForWildcard() { public void testEmptyClusterSearchForWildcard() {
IndexNotFoundException e = expectThrows(IndexNotFoundException.class, () -> client().prepareSearch("*").get()); SearchResponse searchResponse = client().prepareSearch("*").get();
assertNoSearchHits(searchResponse);
}
public void testEmptyClusterSearchForWildcardDisallowNoIndices() {
IndexNotFoundException e = expectThrows(IndexNotFoundException.class, () -> client().prepareSearch("*")
.setIndicesOptions(IndicesOptions.fromOptions(randomBoolean(), false, true, randomBoolean())).get());
assertEquals("no such index", e.getMessage()); assertEquals("no such index", e.getMessage());
} }
public void testEmptyAuthorizedIndicesSearchForAll() { public void testEmptyAuthorizedIndicesSearchForAll() {
createIndices("index1", "index2"); createIndices("index1", "index2");
IndexNotFoundException e = expectThrows(IndexNotFoundException.class, () -> client().prepareSearch().get()); assertNoSearchHits(client().prepareSearch().get());
}
public void testEmptyAuthorizedIndicesSearchForAllDisallowNoIndices() {
createIndices("index1", "index2");
IndexNotFoundException e = expectThrows(IndexNotFoundException.class, () -> client().prepareSearch()
.setIndicesOptions(IndicesOptions.fromOptions(randomBoolean(), false, true, randomBoolean())).get());
assertEquals("no such index", e.getMessage()); assertEquals("no such index", e.getMessage());
} }
public void testEmptyAuthorizedIndicesSearchForWildcard() { public void testEmptyAuthorizedIndicesSearchForWildcard() {
createIndices("index1", "index2"); createIndices("index1", "index2");
IndexNotFoundException e = expectThrows(IndexNotFoundException.class, () -> client().prepareSearch("*").get()); assertNoSearchHits(client().prepareSearch("*").get());
}
public void testEmptyAuthorizedIndicesSearchForWildcardDisallowNoIndices() {
createIndices("index1", "index2");
IndexNotFoundException e = expectThrows(IndexNotFoundException.class, () -> client().prepareSearch("*")
.setIndicesOptions(IndicesOptions.fromOptions(randomBoolean(), false, true, randomBoolean())).get());
assertEquals("no such index", e.getMessage()); assertEquals("no such index", e.getMessage());
} }
@ -103,6 +134,21 @@ public class IndicesAndAliasesResolverIntegrationTests extends SecurityIntegTest
assertReturnedIndices(client().prepareSearch("missing", "test*").setIndicesOptions(indicesOptions).get(), "test1", "test2"); assertReturnedIndices(client().prepareSearch("missing", "test*").setIndicesOptions(indicesOptions).get(), "test1", "test2");
assertReturnedIndices(client().prepareSearch("missing_*", "test*").setIndicesOptions(indicesOptions).get(), "test1", "test2"); assertReturnedIndices(client().prepareSearch("missing_*", "test*").setIndicesOptions(indicesOptions).get(), "test1", "test2");
//an unauthorized index is the same as a missing one
assertNoSearchHits(client().prepareSearch("missing").setIndicesOptions(indicesOptions).get());
assertNoSearchHits(client().prepareSearch("index1").setIndicesOptions(indicesOptions).get());
assertNoSearchHits(client().prepareSearch("missing", "index1").setIndicesOptions(indicesOptions).get());
assertNoSearchHits(client().prepareSearch("does_not_match_any_*").setIndicesOptions(indicesOptions).get());
assertNoSearchHits(client().prepareSearch("does_not_match_any_*", "index1").setIndicesOptions(indicesOptions).get());
assertNoSearchHits(client().prepareSearch("index*").setIndicesOptions(indicesOptions).get());
assertNoSearchHits(client().prepareSearch("index*", "missing").setIndicesOptions(indicesOptions).get());
} }
public void testExplicitExclusion() { public void testExplicitExclusion() {
@ -145,6 +191,10 @@ public class IndicesAndAliasesResolverIntegrationTests extends SecurityIntegTest
assertReturnedIndices(searchResponse, "test10"); assertReturnedIndices(searchResponse, "test10");
} }
public void testMissingDateMath() {
expectThrows(IndexNotFoundException.class, () -> client().prepareSearch("<logstash-{now/M}>").get());
}
public void testMultiSearchUnauthorizedIndex() { public void testMultiSearchUnauthorizedIndex() {
//index1 is not authorized, the whole request fails due to that //index1 is not authorized, the whole request fails due to that
createIndices("test1", "test2", "test3", "index1"); createIndices("test1", "test2", "test3", "index1");
@ -171,6 +221,7 @@ public class IndicesAndAliasesResolverIntegrationTests extends SecurityIntegTest
assertThat(multiSearchResponse.getResponses()[1].getFailure().toString(), equalTo("[test4] IndexNotFoundException[no such index]")); assertThat(multiSearchResponse.getResponses()[1].getFailure().toString(), equalTo("[test4] IndexNotFoundException[no such index]"));
} }
@AwaitsFix(bugUrl = "multi requests endpoints need fixing, we shouldn't merge all the indices in one collection")
public void testMultiSearchWildcard() { public void testMultiSearchWildcard() {
//test4 is missing but authorized, only that specific item fails //test4 is missing but authorized, only that specific item fails
createIndices("test1", "test2", "test3", "index1"); createIndices("test1", "test2", "test3", "index1");

View File

@ -86,9 +86,6 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase {
assertThat(getWatchResponse.getSource(), notNullValue()); assertThat(getWatchResponse.getSource(), notNullValue());
} }
@AwaitsFix(bugUrl = "https://github.com/elastic/x-plugins/issues/1250")
//this test is temporarily disabled. The security plugin honours now ignore_unavailable, but whenever there's a request left
//with an empty set of indices it throws exception. This will be fixed once security plugin honours allow_no_indices too.
public void testIndexWatchRegisterWatchBeforeTargetIndex() throws Exception { public void testIndexWatchRegisterWatchBeforeTargetIndex() throws Exception {
WatcherClient watcherClient = watcherClient(); WatcherClient watcherClient = watcherClient();
WatcherSearchTemplateRequest searchRequest = templateRequest(searchSource().query(termQuery("field", "value")), "idx"); WatcherSearchTemplateRequest searchRequest = templateRequest(searchSource().query(termQuery("field", "value")), "idx");
@ -172,9 +169,6 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase {
} }
} }
@AwaitsFix(bugUrl = "https://github.com/elastic/x-plugins/issues/1250")
//this test is temporarily disabled. The security plugin honours now ignore_unavailable, but whenever there's a request left
//with an empty set of indices it throws exception. This will be fixed once security plugin honours allow_no_indices too.
public void testModifyWatches() throws Exception { public void testModifyWatches() throws Exception {
WatcherSearchTemplateRequest searchRequest = templateRequest(searchSource().query(matchAllQuery()), "idx"); WatcherSearchTemplateRequest searchRequest = templateRequest(searchSource().query(matchAllQuery()), "idx");

View File

@ -238,9 +238,6 @@ public class BootStrapTests extends AbstractWatcherIntegrationTestCase {
assertThat(response.getWatchesCount(), equalTo((long) numWatches)); assertThat(response.getWatchesCount(), equalTo((long) numWatches));
} }
@AwaitsFix(bugUrl = "https://github.com/elastic/x-plugins/issues/1250")
//this test is temporarily disabled. The security plugin honours now ignore_unavailable, but whenever there's a request left
//with an empty set of indices it throws exception. This will be fixed once security plugin honours allow_no_indices too.
@TestLogging("org.elasticsearch.watcher.actions:DEBUG") @TestLogging("org.elasticsearch.watcher.actions:DEBUG")
public void testTriggeredWatchLoading() throws Exception { public void testTriggeredWatchLoading() throws Exception {
createIndex("output"); createIndex("output");
@ -298,9 +295,6 @@ public class BootStrapTests extends AbstractWatcherIntegrationTestCase {
}, 30, TimeUnit.SECONDS); }, 30, TimeUnit.SECONDS);
} }
@AwaitsFix(bugUrl = "https://github.com/elastic/x-plugins/issues/1250")
//this test is temporarily disabled. The security plugin honours now ignore_unavailable, but whenever there's a request left
//with an empty set of indices it throws exception. This will be fixed once security plugin honours allow_no_indices too.
public void testMixedTriggeredWatchLoading() throws Exception { public void testMixedTriggeredWatchLoading() throws Exception {
createIndex("output"); createIndex("output");
WatcherStatsResponse response = watcherClient().prepareWatcherStats().get(); WatcherStatsResponse response = watcherClient().prepareWatcherStats().get();

View File

@ -73,9 +73,6 @@ public class WatchMetadataTests extends AbstractWatcherIntegrationTestCase {
assertThat(searchResponse.getHits().getTotalHits(), greaterThan(0L)); assertThat(searchResponse.getHits().getTotalHits(), greaterThan(0L));
} }
@AwaitsFix(bugUrl = "https://github.com/elastic/x-plugins/issues/1250")
//this test is temporarily disabled. The security plugin honours now ignore_unavailable, but whenever there's a request left
//with an empty set of indices it throws exception. This will be fixed once security plugin honours allow_no_indices too.
public void testWatchMetadataAvailableAtExecution() throws Exception { public void testWatchMetadataAvailableAtExecution() throws Exception {
Map<String, Object> metadata = new HashMap<>(); Map<String, Object> metadata = new HashMap<>();
metadata.put("foo", "bar"); metadata.put("foo", "bar");

View File

@ -7,34 +7,11 @@ dependencies {
integTest { integTest {
includePackaged true includePackaged true
systemProperty 'tests.rest.blacklist', systemProperty 'tests.rest.blacklist',
['indices.get/10_basic/*allow_no_indices*', ['cat.aliases/10_basic/Empty cluster',
'indices.get/10_basic/Missing index should return empty object if ignore_unavailable',
'cat.count/10_basic/Test cat count output',
'cat.aliases/10_basic/Empty cluster',
'indices.segments/10_basic/no segments test',
'indices.clear_cache/10_basic/clear_cache test',
'indices.status/10_basic/Indices status test',
'cat.indices/10_basic/Test cat indices output',
'cat.recovery/10_basic/Test cat recovery output',
'cat.shards/10_basic/Test cat shards output',
'termvector/20_issue7121/*',
'index/10_with_id/Index with ID', 'index/10_with_id/Index with ID',
'indices.get_alias/20_emtpy/*',
'cat.segments/10_basic/Test cat segments output',
'indices.put_settings/10_basic/Test indices settings allow_no_indices',
'indices.put_settings/10_basic/Test indices settings ignore_unavailable',
'indices.refresh/10_basic/Indices refresh test no-match wildcard',
'indices.stats/10_index/Index - star*',
'indices.recovery/10_basic/Indices recovery test*',
'indices.shard_stores/10_basic/no indices test',
'cat.nodeattrs/10_basic/Test cat nodes attrs output',
'bulk/40_fields/Fields',
'indices.get_alias/10_basic/Get alias against closed indices', 'indices.get_alias/10_basic/Get alias against closed indices',
'ingest/70_bulk/*',
'ingest/10_crud/Check availability of default processors',
'search/80_date_math_index_names/Missing index with catch',
'cat.templates/10_basic/No templates', 'cat.templates/10_basic/No templates',
'cat.templates/10_basic/Sort templates', 'cat.templates/10_basic/Sort templates'
].join(',') ].join(',')
cluster { cluster {