Skip to content

Commit 5f64343

Browse files
authored
Prohibit the usage of create index api in namespaces managed by data stream templates (#62574)
Backport of #62527 to 7.x branch. This commit adds validation that prohibits the creation of regular indices in the namespace of templates with data streams enabled. It shouldn't be possible to create ordinary indices when the name of the index matches with a composable index template that enables data streams. Auto creation has logic that creates data streams instead of regular indices. However validation logic for the create index api was missing.
1 parent df93b31 commit 5f64343

File tree

7 files changed

+50
-15
lines changed

7 files changed

+50
-15
lines changed

server/src/main/java/org/elasticsearch/action/admin/indices/create/AutoCreateAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
import java.util.concurrent.atomic.AtomicReference;
4949

5050
/**
51-
* Api that auto creates an index that originate from requests that write into an index that doesn't yet exist.
51+
* Api that auto creates an index or data stream that originate from requests that write into an index that doesn't yet exist.
5252
*/
5353
public final class AutoCreateAction extends ActionType<CreateIndexResponse> {
5454

server/src/main/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,13 @@ private ClusterState applyCreateIndexRequestWithV2Template(final ClusterState cu
508508
throws Exception {
509509
logger.debug("applying create index request using composable template [{}]", templateName);
510510

511+
ComposableIndexTemplate template = currentState.getMetadata().templatesV2().get(templateName);
512+
if (request.dataStreamName() == null && template.getDataStreamTemplate() != null) {
513+
throw new IllegalArgumentException("cannot create index with name [" + request.index() +
514+
"], because it matches with template [" + templateName + "] that creates data streams only, " +
515+
"use create data stream api instead");
516+
}
517+
511518
final List<Map<String, Map<String, Object>>> mappings =
512519
collectV2Mappings(request.mappings(), currentState, templateName, xContentRegistry, request.index());
513520
final Settings aggregatedIndexSettings =

x-pack/plugin/ccr/qa/security/follower-roles.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ ccruser:
22
cluster:
33
- manage_ccr
44
indices:
5-
- names: [ 'allowed-index', 'forget-follower', 'logs-eu-*' ]
5+
- names: [ 'allowed-index', 'forget-follower', 'logs-eu*' ]
66
privileges:
77
- monitor
88
- read

x-pack/plugin/ccr/qa/security/leader-roles.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ ccruser:
22
cluster:
33
- read_ccr
44
indices:
5-
- names: [ 'allowed-index', 'clean-leader', 'forget-leader', 'logs-eu-*' ]
5+
- names: [ 'allowed-index', 'clean-leader', 'forget-leader', 'logs-eu*' ]
66
privileges:
77
- monitor
88
- read

x-pack/plugin/ccr/qa/security/src/test/java/org/elasticsearch/xpack/ccr/FollowIndexSecurityIT.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ public void testFollowIndex() throws Exception {
132132

133133
public void testAutoFollowPatterns() throws Exception {
134134
assumeFalse("Test should only run when both clusters are running", "leader".equals(targetCluster));
135-
String allowedIndex = "logs-eu-20190101";
136-
String disallowedIndex = "logs-us-20190101";
135+
String allowedIndex = "logs-eu_20190101";
136+
String disallowedIndex = "logs-us_20190101";
137137

138138
{
139139
Request request = new Request("PUT", "/_ccr/auto_follow/test_pattern");
@@ -143,7 +143,7 @@ public void testAutoFollowPatterns() throws Exception {
143143
}
144144

145145
Request request = new Request("PUT", "/_ccr/auto_follow/test_pattern");
146-
request.setJsonEntity("{\"leader_index_patterns\": [\"logs-eu-*\"], \"remote_cluster\": \"leader_cluster\"}");
146+
request.setJsonEntity("{\"leader_index_patterns\": [\"logs-eu*\"], \"remote_cluster\": \"leader_cluster\"}");
147147
assertOK(client().performRequest(request));
148148

149149
try (RestClient leaderClient = buildLeaderClient()) {

x-pack/plugin/src/test/resources/rest-api-spec/test/data_stream/10_basic.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,3 +399,31 @@ setup:
399399
indices.delete_data_stream:
400400
name: logs-foobar
401401
- is_true: acknowledged
402+
403+
---
404+
"Create index into a namespace that is governed by a data stream template":
405+
- skip:
406+
version: " - 7.99.99"
407+
reason: "adjust until #62527 is fully backported"
408+
features: allowed_warnings
409+
410+
- do:
411+
allowed_warnings:
412+
- "index template [generic_logs_template] has index patterns [logs-*] matching patterns from existing older templates [global] with patterns (global => [*]); this template [generic_logs_template] will take precedence during new index creation"
413+
indices.put_index_template:
414+
name: generic_logs_template
415+
body:
416+
index_patterns: logs-*
417+
data_stream: {}
418+
419+
# test response status code
420+
- do:
421+
catch: bad_request
422+
indices.create:
423+
index: logs-foobar
424+
425+
# test error message
426+
- do:
427+
catch: /cannot create index with name \[logs-foobar\], because it matches with template \[generic_logs_template\] that creates data streams only, use create data stream api instead/
428+
indices.create:
429+
index: logs-foobar

x-pack/plugin/src/test/resources/rest-api-spec/test/security/authz/50_data_streams.yml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ setup:
1515
body: >
1616
{
1717
"indices": [
18-
{ "names": ["simple*"], "privileges": ["read", "write", "create_index", "view_index_metadata", "monitor", "delete_index"] }
18+
{ "names": ["simple*", "easy*"], "privileges": ["read", "write", "create_index", "view_index_metadata", "monitor", "delete_index"] }
1919
]
2020
}
2121
@@ -66,7 +66,7 @@ setup:
6666
indices.put_index_template:
6767
name: my-template1
6868
body:
69-
index_patterns: [s*, create-doc-data-stream1, write-data-stream1]
69+
index_patterns: [s*, easy-data-stream1, create-doc-data-stream1, write-data-stream1]
7070
template:
7171
mappings:
7272
properties:
@@ -174,27 +174,27 @@ teardown:
174174

175175
- do: # superuser
176176
indices.create_data_stream:
177-
name: simple-data-stream1
177+
name: easy-data-stream1
178178
- is_true: acknowledged
179179

180180
- do: # superuser
181181
indices.create:
182-
index: simple-index
182+
index: easy-index
183183
body:
184184
aliases:
185-
simple-alias: {}
185+
easy-alias: {}
186186

187187
- do:
188188
headers: { Authorization: "Basic dGVzdF91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" } # test_user
189189
indices.get_alias:
190-
name: simple*
190+
name: easy*
191191

192-
- match: {simple-index.aliases.simple-alias: {}}
193-
- is_false: simple-data-stream1
192+
- match: {easy-index.aliases.easy-alias: {}}
193+
- is_false: easy-data-stream1
194194

195195
- do: # superuser
196196
indices.delete_data_stream:
197-
name: simple-data-stream1
197+
name: easy-data-stream1
198198
- is_true: acknowledged
199199

200200
---

0 commit comments

Comments
 (0)