Skip to content

Commit 4dee9ee

Browse files
authored
Add more validation for data stream aliases. (#73463)
Backport #73416 to 7.x branch. Currently when attempting to an alias to points to both data streams and regular indices the alias does get created, but points only to data streams. With this change attempting to add such aliases results in a client error. Currently when adding data stream aliases with unsupported parameters (e.g. filter or routing) the alias does get created, but without the unsupported parameters. With this change attempting to create aliases to point to data streams with unsupported parameters will result in a client error. Relates to #66163
1 parent b934c9b commit 4dee9ee

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

server/src/main/java/org/elasticsearch/action/admin/indices/alias/IndicesAliasesRequest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,10 @@ public AliasActions searchRouting(String searchRouting) {
384384
return this;
385385
}
386386

387+
public String routing() {
388+
return routing;
389+
}
390+
387391
public String indexRouting() {
388392
return indexRouting == null ? routing : indexRouting;
389393
}

server/src/main/java/org/elasticsearch/action/admin/indices/alias/TransportIndicesAliasesAction.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@
3535
import org.elasticsearch.transport.TransportService;
3636

3737
import java.util.ArrayList;
38+
import java.util.Arrays;
3839
import java.util.Collections;
3940
import java.util.HashSet;
4041
import java.util.List;
4142
import java.util.Objects;
4243
import java.util.Optional;
4344
import java.util.Set;
45+
import java.util.stream.Collectors;
4446

4547
import static java.util.Collections.unmodifiableList;
4648

@@ -91,6 +93,38 @@ protected void masterOperation(final IndicesAliasesRequest request, final Cluste
9193
List<String> concreteDataStreams =
9294
indexNameExpressionResolver.dataStreamNames(state, request.indicesOptions(), action.indices());
9395
if (concreteDataStreams.size() != 0) {
96+
// Fail if parameters are used that data streams don't support:
97+
if (action.filter() != null) {
98+
throw new IllegalArgumentException("aliases that point to data streams don't support filters");
99+
}
100+
if (action.routing() != null) {
101+
throw new IllegalArgumentException("aliases that point to data streams don't support routing");
102+
}
103+
if (action.indexRouting() != null) {
104+
throw new IllegalArgumentException("aliases that point to data streams don't support index_routing");
105+
}
106+
if (action.searchRouting() != null) {
107+
throw new IllegalArgumentException("aliases that point to data streams don't support search_routing");
108+
}
109+
if (action.writeIndex() != null) {
110+
throw new IllegalArgumentException("aliases that point to data streams don't support is_write_index");
111+
}
112+
if (action.isHidden() != null) {
113+
throw new IllegalArgumentException("aliases that point to data streams don't support is_hidden");
114+
}
115+
// Fail if expressions match both data streams and regular indices:
116+
String[] concreteIndices =
117+
indexNameExpressionResolver.concreteIndexNames(state, request.indicesOptions(), true, action.indices());
118+
List<String> nonBackingIndices = Arrays.stream(concreteIndices)
119+
.map(resolvedIndex -> state.metadata().getIndicesLookup().get(resolvedIndex))
120+
.filter(ia -> ia.getParentDataStream() == null)
121+
.map(IndexAbstraction::getName)
122+
.collect(Collectors.toList());
123+
if (nonBackingIndices.isEmpty() == false) {
124+
throw new IllegalArgumentException("expressions " + Arrays.toString(action.indices()) +
125+
" that match with both data streams and regular indices are disallowed");
126+
}
127+
94128
switch (action.actionType()) {
95129
case ADD:
96130
for (String dataStreamName : concreteDataStreams) {

x-pack/plugin/data-streams/src/internalClusterTest/java/org/elasticsearch/datastreams/DataStreamIT.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,96 @@ public void testAliasActionsFailOnDataStreamBackingIndices() throws Exception {
737737
);
738738
}
739739

740+
public void testDataStreamAliasesMixedExpressionValidation() throws Exception {
741+
createIndex("metrics-myindex");
742+
putComposableIndexTemplate("id1", List.of("metrics-*"));
743+
String dataStreamName = "metrics-foo";
744+
CreateDataStreamAction.Request createDataStreamRequest = new CreateDataStreamAction.Request(dataStreamName);
745+
client().execute(CreateDataStreamAction.INSTANCE, createDataStreamRequest).get();
746+
747+
AliasActions addAction = new AliasActions(AliasActions.Type.ADD).index("metrics-*").aliases("my-alias");
748+
IndicesAliasesRequest aliasesAddRequest = new IndicesAliasesRequest();
749+
aliasesAddRequest.addAliasAction(addAction);
750+
Exception e = expectThrows(IllegalArgumentException.class, () -> client().admin().indices().aliases(aliasesAddRequest).actionGet());
751+
assertThat(e.getMessage(), equalTo("expressions [metrics-*] that match with both data streams and regular indices are disallowed"));
752+
}
753+
754+
public void testDataStreamAliasesUnsupportedParametersValidation() throws Exception {
755+
putComposableIndexTemplate("id1", List.of("metrics-*"));
756+
String dataStreamName = "metrics-foo";
757+
CreateDataStreamAction.Request createDataStreamRequest = new CreateDataStreamAction.Request(dataStreamName);
758+
client().execute(CreateDataStreamAction.INSTANCE, createDataStreamRequest).get();
759+
760+
{
761+
AliasActions addAction = new AliasActions(AliasActions.Type.ADD).index("metrics-*").aliases("my-alias").filter("[filter]");
762+
IndicesAliasesRequest aliasesAddRequest = new IndicesAliasesRequest();
763+
aliasesAddRequest.addAliasAction(addAction);
764+
Exception e = expectThrows(
765+
IllegalArgumentException.class,
766+
() -> client().admin().indices().aliases(aliasesAddRequest).actionGet()
767+
);
768+
assertThat(e.getMessage(), equalTo("aliases that point to data streams don't support filters"));
769+
}
770+
{
771+
AliasActions addAction = new AliasActions(AliasActions.Type.ADD).index("metrics-*").aliases("my-alias").routing("[routing]");
772+
IndicesAliasesRequest aliasesAddRequest = new IndicesAliasesRequest();
773+
aliasesAddRequest.addAliasAction(addAction);
774+
Exception e = expectThrows(
775+
IllegalArgumentException.class,
776+
() -> client().admin().indices().aliases(aliasesAddRequest).actionGet()
777+
);
778+
assertThat(e.getMessage(), equalTo("aliases that point to data streams don't support routing"));
779+
}
780+
{
781+
AliasActions addAction = new AliasActions(AliasActions.Type.ADD).index("metrics-*")
782+
.aliases("my-alias")
783+
.indexRouting("[index_routing]");
784+
IndicesAliasesRequest aliasesAddRequest = new IndicesAliasesRequest();
785+
aliasesAddRequest.addAliasAction(addAction);
786+
Exception e = expectThrows(
787+
IllegalArgumentException.class,
788+
() -> client().admin().indices().aliases(aliasesAddRequest).actionGet()
789+
);
790+
assertThat(e.getMessage(), equalTo("aliases that point to data streams don't support index_routing"));
791+
}
792+
{
793+
AliasActions addAction = new AliasActions(AliasActions.Type.ADD).index("metrics-*")
794+
.aliases("my-alias")
795+
.searchRouting("[search_routing]");
796+
IndicesAliasesRequest aliasesAddRequest = new IndicesAliasesRequest();
797+
aliasesAddRequest.addAliasAction(addAction);
798+
Exception e = expectThrows(
799+
IllegalArgumentException.class,
800+
() -> client().admin().indices().aliases(aliasesAddRequest).actionGet()
801+
);
802+
assertThat(e.getMessage(), equalTo("aliases that point to data streams don't support search_routing"));
803+
}
804+
{
805+
AliasActions addAction = new AliasActions(AliasActions.Type.ADD).index("metrics-*")
806+
.aliases("my-alias")
807+
.writeIndex(randomBoolean());
808+
IndicesAliasesRequest aliasesAddRequest = new IndicesAliasesRequest();
809+
aliasesAddRequest.addAliasAction(addAction);
810+
Exception e = expectThrows(
811+
IllegalArgumentException.class,
812+
() -> client().admin().indices().aliases(aliasesAddRequest).actionGet()
813+
);
814+
assertThat(e.getMessage(), equalTo("aliases that point to data streams don't support is_write_index"));
815+
}
816+
{
817+
AliasActions addAction = new AliasActions(AliasActions.Type.ADD).index("metrics-*")
818+
.aliases("my-alias")
819+
.isHidden(randomBoolean());
820+
IndicesAliasesRequest aliasesAddRequest = new IndicesAliasesRequest();
821+
aliasesAddRequest.addAliasAction(addAction);
822+
Exception e = expectThrows(
823+
IllegalArgumentException.class,
824+
() -> client().admin().indices().aliases(aliasesAddRequest).actionGet()
825+
);
826+
assertThat(e.getMessage(), equalTo("aliases that point to data streams don't support is_hidden"));
827+
}
828+
}
829+
740830
public void testTimestampFieldCustomAttributes() throws Exception {
741831
String mapping = "{\n"
742832
+ " \"properties\": {\n"

0 commit comments

Comments
 (0)