Skip to content

Commit aa123af

Browse files
martijnvgbrusic
authored andcommitted
Added action.destructive_requires_name that controls whether wildcard expressions and _all is allowed to be used for destructive operat Also the delete index api requires always an index to be specified (either concrete index, alias or wildcard expression)
Closes elastic#4549 elastic#4481
1 parent 93f00e6 commit aa123af

18 files changed

+397
-124
lines changed

docs/reference/indices/delete-index.asciidoc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ The delete index API allows to delete an existing index.
88
$ curl -XDELETE 'http://localhost:9200/twitter/'
99
--------------------------------------------------
1010

11-
The above example deletes an index called `twitter`.
11+
The above example deletes an index called `twitter`. Specifying an index,
12+
alias or wildcard expression is required.
1213

1314
The delete index API can also be applied to more than one index, or on
14-
`_all` indices (be careful!). All indices will also be deleted when no
15-
specific index is provided. In order to disable allowing to delete all
16-
indices, set `action.disable_delete_all_indices` setting in the config
17-
to `true`.
15+
all indices (be careful!) by using `_all` or `*` as index.
16+
17+
In order to disable allowing to delete indices via wildcards or `_all`,
18+
set `action.destructive_requires_name` setting in the config to `true`.
19+
This setting can also be changed via the cluster update settings api.

docs/reference/indices/open-close.asciidoc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ disabled using the `ignore_unavailable=true` parameter.
2323

2424
All indices can be opened or closed at once using `_all` as the index name
2525
or specifying patterns that identify them all (e.g. `*`).
26-
Closing all indices can be disabled by setting the `action.disable_close_all_indices`
27-
flag in the config file to `true`.
2826

27+
Identifying indices via wildcards or `_all` can be disabled by setting the
28+
`action.destructive_requires_name` flag in the config file to `true`.
29+
This setting can also be changed via the cluster update settings api.

rest-api-spec/api/indices.delete.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"parts": {
99
"index": {
1010
"type" : "list",
11-
"description" : "A comma-separated list of indices to delete; use `_all` or empty string to delete all indices"
11+
"description" : "A comma-separated list of indices to delete; use `_all` or `*` string to delete all indices"
1212
}
1313
},
1414
"params": {

src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
package org.elasticsearch.action.admin.indices.close;
2121

2222
import org.elasticsearch.ElasticsearchException;
23-
import org.elasticsearch.ElasticsearchIllegalArgumentException;
2423
import org.elasticsearch.action.ActionListener;
24+
import org.elasticsearch.action.support.DestructiveOperations;
2525
import org.elasticsearch.action.support.master.TransportMasterNodeOperationAction;
2626
import org.elasticsearch.cluster.ClusterService;
2727
import org.elasticsearch.cluster.ClusterState;
@@ -32,6 +32,7 @@
3232
import org.elasticsearch.cluster.metadata.MetaDataIndexStateService;
3333
import org.elasticsearch.common.inject.Inject;
3434
import org.elasticsearch.common.settings.Settings;
35+
import org.elasticsearch.node.settings.NodeSettingsService;
3536
import org.elasticsearch.threadpool.ThreadPool;
3637
import org.elasticsearch.transport.TransportService;
3738

@@ -41,15 +42,14 @@
4142
public class TransportCloseIndexAction extends TransportMasterNodeOperationAction<CloseIndexRequest, CloseIndexResponse> {
4243

4344
private final MetaDataIndexStateService indexStateService;
44-
private final boolean disableCloseAllIndices;
45-
45+
private final DestructiveOperations destructiveOperations;
4646

4747
@Inject
4848
public TransportCloseIndexAction(Settings settings, TransportService transportService, ClusterService clusterService,
49-
ThreadPool threadPool, MetaDataIndexStateService indexStateService) {
49+
ThreadPool threadPool, MetaDataIndexStateService indexStateService, NodeSettingsService nodeSettingsService) {
5050
super(settings, transportService, clusterService, threadPool);
5151
this.indexStateService = indexStateService;
52-
this.disableCloseAllIndices = settings.getAsBoolean("action.disable_close_all_indices", false);
52+
this.destructiveOperations = new DestructiveOperations(logger, settings, nodeSettingsService);
5353
}
5454

5555
@Override
@@ -75,17 +75,7 @@ protected CloseIndexResponse newResponse() {
7575

7676
@Override
7777
protected void doExecute(CloseIndexRequest request, ActionListener<CloseIndexResponse> listener) {
78-
ClusterState state = clusterService.state();
79-
String[] indicesOrAliases = request.indices();
80-
request.indices(state.metaData().concreteIndices(indicesOrAliases, request.indicesOptions()));
81-
82-
if (disableCloseAllIndices) {
83-
if (state.metaData().isExplicitAllIndices(indicesOrAliases) ||
84-
state.metaData().isPatternMatchingAllIndices(indicesOrAliases, request.indices())) {
85-
throw new ElasticsearchIllegalArgumentException("closing all indices is disabled");
86-
}
87-
}
88-
78+
destructiveOperations.failDestructive(request.indices());
8979
super.doExecute(request, listener);
9080
}
9181

@@ -96,7 +86,7 @@ protected ClusterBlockException checkBlock(CloseIndexRequest request, ClusterSta
9686

9787
@Override
9888
protected void masterOperation(final CloseIndexRequest request, final ClusterState state, final ActionListener<CloseIndexResponse> listener) throws ElasticsearchException {
99-
89+
request.indices(state.metaData().concreteIndices(request.indices(), request.indicesOptions()));
10090
CloseIndexClusterStateUpdateRequest updateRequest = new CloseIndexClusterStateUpdateRequest()
10191
.ackTimeout(request.timeout()).masterNodeTimeout(request.masterNodeTimeout())
10292
.indices(request.indices());

src/main/java/org/elasticsearch/action/admin/indices/delete/DeleteIndexRequest.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public DeleteIndexRequest indicesOptions(IndicesOptions indicesOptions) {
6868
@Override
6969
public ActionRequestValidationException validate() {
7070
ActionRequestValidationException validationException = null;
71-
if (indices == null) {
71+
if (indices == null || indices.length == 0) {
7272
validationException = addValidationError("index / indices is missing", validationException);
7373
}
7474
return validationException;
@@ -114,25 +114,15 @@ public DeleteIndexRequest timeout(String timeout) {
114114
@Override
115115
public void readFrom(StreamInput in) throws IOException {
116116
super.readFrom(in);
117-
indices = new String[in.readVInt()];
118-
for (int i = 0; i < indices.length; i++) {
119-
indices[i] = in.readString();
120-
}
117+
indices = in.readStringArray();
121118
indicesOptions = IndicesOptions.readIndicesOptions(in);
122119
timeout = readTimeValue(in);
123120
}
124121

125122
@Override
126123
public void writeTo(StreamOutput out) throws IOException {
127124
super.writeTo(out);
128-
if (indices == null) {
129-
out.writeVInt(0);
130-
} else {
131-
out.writeVInt(indices.length);
132-
for (String index : indices) {
133-
out.writeString(index);
134-
}
135-
}
125+
out.writeStringArray(indices);
136126
indicesOptions.writeIndicesOptions(out);
137127
timeout.writeTo(out);
138128
}

src/main/java/org/elasticsearch/action/admin/indices/delete/TransportDeleteIndexAction.java

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@
2020
package org.elasticsearch.action.admin.indices.delete;
2121

2222
import org.elasticsearch.ElasticsearchException;
23-
import org.elasticsearch.ElasticsearchIllegalArgumentException;
2423
import org.elasticsearch.action.ActionListener;
25-
import org.elasticsearch.action.admin.indices.mapping.delete.TransportDeleteMappingAction;
24+
import org.elasticsearch.action.support.DestructiveOperations;
2625
import org.elasticsearch.action.support.master.TransportMasterNodeOperationAction;
2726
import org.elasticsearch.cluster.ClusterService;
2827
import org.elasticsearch.cluster.ClusterState;
@@ -32,6 +31,7 @@
3231
import org.elasticsearch.common.inject.Inject;
3332
import org.elasticsearch.common.settings.Settings;
3433
import org.elasticsearch.common.util.concurrent.CountDown;
34+
import org.elasticsearch.node.settings.NodeSettingsService;
3535
import org.elasticsearch.threadpool.ThreadPool;
3636
import org.elasticsearch.transport.TransportService;
3737

@@ -41,19 +41,15 @@
4141
public class TransportDeleteIndexAction extends TransportMasterNodeOperationAction<DeleteIndexRequest, DeleteIndexResponse> {
4242

4343
private final MetaDataDeleteIndexService deleteIndexService;
44-
45-
private final TransportDeleteMappingAction deleteMappingAction;
46-
47-
private final boolean disableDeleteAllIndices;
44+
private final DestructiveOperations destructiveOperations;
4845

4946
@Inject
5047
public TransportDeleteIndexAction(Settings settings, TransportService transportService, ClusterService clusterService,
51-
ThreadPool threadPool, MetaDataDeleteIndexService deleteIndexService, TransportDeleteMappingAction deleteMappingAction) {
48+
ThreadPool threadPool, MetaDataDeleteIndexService deleteIndexService,
49+
NodeSettingsService nodeSettingsService) {
5250
super(settings, transportService, clusterService, threadPool);
5351
this.deleteIndexService = deleteIndexService;
54-
this.deleteMappingAction = deleteMappingAction;
55-
56-
this.disableDeleteAllIndices = settings.getAsBoolean("action.disable_delete_all_indices", false);
52+
this.destructiveOperations = new DestructiveOperations(logger, settings, nodeSettingsService);
5753
}
5854

5955
@Override
@@ -78,17 +74,7 @@ protected DeleteIndexResponse newResponse() {
7874

7975
@Override
8076
protected void doExecute(DeleteIndexRequest request, ActionListener<DeleteIndexResponse> listener) {
81-
ClusterState state = clusterService.state();
82-
String[] indicesOrAliases = request.indices();
83-
84-
request.indices(state.metaData().concreteIndices(request.indices(), request.indicesOptions()));
85-
86-
if (disableDeleteAllIndices) {
87-
if (state.metaData().isAllIndices(indicesOrAliases) ||
88-
state.metaData().isPatternMatchingAllIndices(indicesOrAliases, request.indices())) {
89-
throw new ElasticsearchIllegalArgumentException("deleting all indices is disabled");
90-
}
91-
}
77+
destructiveOperations.failDestructive(request.indices());
9278
super.doExecute(request, listener);
9379
}
9480

@@ -99,6 +85,7 @@ protected ClusterBlockException checkBlock(DeleteIndexRequest request, ClusterSt
9985

10086
@Override
10187
protected void masterOperation(final DeleteIndexRequest request, final ClusterState state, final ActionListener<DeleteIndexResponse> listener) throws ElasticsearchException {
88+
request.indices(state.metaData().concreteIndices(request.indices(), request.indicesOptions()));
10289
if (request.indices().length == 0) {
10390
listener.onResponse(new DeleteIndexResponse(true));
10491
return;

src/main/java/org/elasticsearch/action/admin/indices/mapping/delete/TransportDeleteMappingAction.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.elasticsearch.action.admin.indices.refresh.TransportRefreshAction;
2828
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
2929
import org.elasticsearch.action.deletebyquery.TransportDeleteByQueryAction;
30+
import org.elasticsearch.action.support.DestructiveOperations;
3031
import org.elasticsearch.action.support.QuerySourceBuilder;
3132
import org.elasticsearch.action.support.master.TransportMasterNodeOperationAction;
3233
import org.elasticsearch.client.Requests;
@@ -41,6 +42,7 @@
4142
import org.elasticsearch.common.settings.Settings;
4243
import org.elasticsearch.index.query.FilterBuilders;
4344
import org.elasticsearch.index.query.QueryBuilders;
45+
import org.elasticsearch.node.settings.NodeSettingsService;
4446
import org.elasticsearch.threadpool.ThreadPool;
4547
import org.elasticsearch.transport.TransportService;
4648

@@ -53,16 +55,19 @@ public class TransportDeleteMappingAction extends TransportMasterNodeOperationAc
5355
private final TransportFlushAction flushAction;
5456
private final TransportDeleteByQueryAction deleteByQueryAction;
5557
private final TransportRefreshAction refreshAction;
58+
private final DestructiveOperations destructiveOperations;
5659

5760
@Inject
5861
public TransportDeleteMappingAction(Settings settings, TransportService transportService, ClusterService clusterService,
5962
ThreadPool threadPool, MetaDataMappingService metaDataMappingService,
60-
TransportDeleteByQueryAction deleteByQueryAction, TransportRefreshAction refreshAction, TransportFlushAction flushAction) {
63+
TransportDeleteByQueryAction deleteByQueryAction, TransportRefreshAction refreshAction,
64+
TransportFlushAction flushAction, NodeSettingsService nodeSettingsService) {
6165
super(settings, transportService, clusterService, threadPool);
6266
this.metaDataMappingService = metaDataMappingService;
6367
this.deleteByQueryAction = deleteByQueryAction;
6468
this.refreshAction = refreshAction;
6569
this.flushAction = flushAction;
70+
this.destructiveOperations = new DestructiveOperations(logger, settings, nodeSettingsService);
6671
}
6772

6873
@Override
@@ -88,7 +93,7 @@ protected DeleteMappingResponse newResponse() {
8893

8994
@Override
9095
protected void doExecute(DeleteMappingRequest request, ActionListener<DeleteMappingResponse> listener) {
91-
request.indices(clusterService.state().metaData().concreteIndices(request.indices(), request.indicesOptions()));
96+
destructiveOperations.failDestructive(request.indices());
9297
super.doExecute(request, listener);
9398
}
9499

@@ -99,6 +104,7 @@ protected ClusterBlockException checkBlock(DeleteMappingRequest request, Cluster
99104

100105
@Override
101106
protected void masterOperation(final DeleteMappingRequest request, final ClusterState state, final ActionListener<DeleteMappingResponse> listener) throws ElasticsearchException {
107+
request.indices(state.metaData().concreteIndices(request.indices(), request.indicesOptions()));
102108
flushAction.execute(Requests.flushRequest(request.indices()), new ActionListener<FlushResponse>() {
103109
@Override
104110
public void onResponse(FlushResponse flushResponse) {

src/main/java/org/elasticsearch/action/admin/indices/open/TransportOpenIndexAction.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.elasticsearch.ElasticsearchException;
2323
import org.elasticsearch.action.ActionListener;
24+
import org.elasticsearch.action.support.DestructiveOperations;
2425
import org.elasticsearch.action.support.master.TransportMasterNodeOperationAction;
2526
import org.elasticsearch.cluster.ClusterService;
2627
import org.elasticsearch.cluster.ClusterState;
@@ -31,6 +32,7 @@
3132
import org.elasticsearch.cluster.metadata.MetaDataIndexStateService;
3233
import org.elasticsearch.common.inject.Inject;
3334
import org.elasticsearch.common.settings.Settings;
35+
import org.elasticsearch.node.settings.NodeSettingsService;
3436
import org.elasticsearch.threadpool.ThreadPool;
3537
import org.elasticsearch.transport.TransportService;
3638

@@ -40,12 +42,14 @@
4042
public class TransportOpenIndexAction extends TransportMasterNodeOperationAction<OpenIndexRequest, OpenIndexResponse> {
4143

4244
private final MetaDataIndexStateService indexStateService;
45+
private final DestructiveOperations destructiveOperations;
4346

4447
@Inject
4548
public TransportOpenIndexAction(Settings settings, TransportService transportService, ClusterService clusterService,
46-
ThreadPool threadPool, MetaDataIndexStateService indexStateService) {
49+
ThreadPool threadPool, MetaDataIndexStateService indexStateService, NodeSettingsService nodeSettingsService) {
4750
super(settings, transportService, clusterService, threadPool);
4851
this.indexStateService = indexStateService;
52+
this.destructiveOperations = new DestructiveOperations(logger, settings, nodeSettingsService);
4953
}
5054

5155
@Override
@@ -71,7 +75,7 @@ protected OpenIndexResponse newResponse() {
7175

7276
@Override
7377
protected void doExecute(OpenIndexRequest request, ActionListener<OpenIndexResponse> listener) {
74-
request.indices(clusterService.state().metaData().concreteIndices(request.indices(), request.indicesOptions()));
78+
destructiveOperations.failDestructive(request.indices());
7579
super.doExecute(request, listener);
7680
}
7781

@@ -82,7 +86,7 @@ protected ClusterBlockException checkBlock(OpenIndexRequest request, ClusterStat
8286

8387
@Override
8488
protected void masterOperation(final OpenIndexRequest request, final ClusterState state, final ActionListener<OpenIndexResponse> listener) throws ElasticsearchException {
85-
89+
request.indices(state.metaData().concreteIndices(request.indices(), request.indicesOptions()));
8690
OpenIndexClusterStateUpdateRequest updateRequest = new OpenIndexClusterStateUpdateRequest()
8791
.ackTimeout(request.timeout()).masterNodeTimeout(request.masterNodeTimeout())
8892
.indices(request.indices());

src/main/java/org/elasticsearch/action/deletebyquery/TransportDeleteByQueryAction.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@
2020
package org.elasticsearch.action.deletebyquery;
2121

2222
import org.elasticsearch.ElasticsearchException;
23+
import org.elasticsearch.action.ActionListener;
24+
import org.elasticsearch.action.support.DestructiveOperations;
2325
import org.elasticsearch.action.support.replication.TransportIndicesReplicationOperationAction;
2426
import org.elasticsearch.cluster.ClusterService;
2527
import org.elasticsearch.cluster.ClusterState;
2628
import org.elasticsearch.cluster.block.ClusterBlockException;
2729
import org.elasticsearch.cluster.block.ClusterBlockLevel;
2830
import org.elasticsearch.common.inject.Inject;
2931
import org.elasticsearch.common.settings.Settings;
32+
import org.elasticsearch.node.settings.NodeSettingsService;
3033
import org.elasticsearch.threadpool.ThreadPool;
3134
import org.elasticsearch.transport.TransportService;
3235

@@ -38,10 +41,20 @@
3841
*/
3942
public class TransportDeleteByQueryAction extends TransportIndicesReplicationOperationAction<DeleteByQueryRequest, DeleteByQueryResponse, IndexDeleteByQueryRequest, IndexDeleteByQueryResponse, ShardDeleteByQueryRequest, ShardDeleteByQueryRequest, ShardDeleteByQueryResponse> {
4043

44+
private final DestructiveOperations destructiveOperations;
45+
4146
@Inject
4247
public TransportDeleteByQueryAction(Settings settings, ClusterService clusterService, TransportService transportService,
43-
ThreadPool threadPool, TransportIndexDeleteByQueryAction indexDeleteByQueryAction) {
48+
ThreadPool threadPool, TransportIndexDeleteByQueryAction indexDeleteByQueryAction,
49+
NodeSettingsService nodeSettingsService) {
4450
super(settings, transportService, clusterService, threadPool, indexDeleteByQueryAction);
51+
this.destructiveOperations = new DestructiveOperations(logger, settings, nodeSettingsService);
52+
}
53+
54+
@Override
55+
protected void doExecute(DeleteByQueryRequest request, ActionListener<DeleteByQueryResponse> listener) {
56+
destructiveOperations.failDestructive(request.indices());
57+
super.doExecute(request, listener);
4558
}
4659

4760
@Override
@@ -82,7 +95,7 @@ protected ClusterBlockException checkGlobalBlock(ClusterState state, DeleteByQue
8295
}
8396

8497
@Override
85-
protected ClusterBlockException checkRequestBlock(ClusterState state, DeleteByQueryRequest replicationPingRequest, String[] concreteIndices) {
98+
protected ClusterBlockException checkRequestBlock(ClusterState state, DeleteByQueryRequest request, String[] concreteIndices) {
8699
return state.blocks().indicesBlockedException(ClusterBlockLevel.WRITE, concreteIndices);
87100
}
88101

0 commit comments

Comments
 (0)