Skip to content

Commit 00dbf11

Browse files
Add remove_index_block arg to _create_from api (#120548) (#120561)
Add a new boolean parameter remove_index_blocks from the _create_from API. If this parameter is set to true, all index block will be filtered out when creating the destination index.
1 parent b02de7e commit 00dbf11

File tree

8 files changed

+149
-29
lines changed

8 files changed

+149
-29
lines changed

docs/changelog/120548.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 120548
2+
summary: Add `remove_index_block` arg to `_create_from` api
3+
area: Indices APIs
4+
type: enhancement
5+
issues: []

rest-api-spec/src/main/resources/rest-api-spec/api/migrate.create_from.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
]
3030
},
3131
"body":{
32-
"description":"The body contains the fields `mappings_override` and `settings_override`.",
32+
"description":"The body contains the fields `mappings_override`, `settings_override`, and `remove_index_blocks`.",
3333
"required":false
3434
}
3535
}

x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceActionIT.java

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ public void testSettingsOverridden() throws Exception {
177177
assertAcked(
178178
client().execute(
179179
CreateIndexFromSourceAction.INSTANCE,
180-
new CreateIndexFromSourceAction.Request(sourceIndex, destIndex, settingsOverride, Map.of())
180+
new CreateIndexFromSourceAction.Request(sourceIndex, destIndex, settingsOverride, Map.of(), randomBoolean())
181181
)
182182
);
183183

@@ -193,7 +193,10 @@ public void testSettingsNullOverride() throws Exception {
193193
assumeTrue("requires the migration reindex feature flag", REINDEX_DATA_STREAM_FEATURE_FLAG.isEnabled());
194194

195195
var sourceIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT);
196-
var sourceSettings = Settings.builder().put(IndexMetadata.SETTING_BLOCKS_WRITE, true).build();
196+
var sourceSettings = Settings.builder()
197+
.put(IndexMetadata.SETTING_BLOCKS_WRITE, true)
198+
.put(IndexMetadata.SETTING_BLOCKS_READ, true)
199+
.build();
197200
indicesAdmin().create(new CreateIndexRequest(sourceIndex, sourceSettings)).get();
198201

199202
Settings settingsOverride = Settings.builder().putNull(IndexMetadata.SETTING_BLOCKS_WRITE).build();
@@ -203,13 +206,55 @@ public void testSettingsNullOverride() throws Exception {
203206
assertAcked(
204207
client().execute(
205208
CreateIndexFromSourceAction.INSTANCE,
206-
new CreateIndexFromSourceAction.Request(sourceIndex, destIndex, settingsOverride, Map.of())
209+
new CreateIndexFromSourceAction.Request(sourceIndex, destIndex, settingsOverride, Map.of(), false)
207210
)
208211
);
209212

210213
// assert settings overridden
211214
var settingsResponse = indicesAdmin().getSettings(new GetSettingsRequest().indices(destIndex)).actionGet();
212-
assertNull(settingsResponse.getSetting(destIndex, IndexMetadata.SETTING_BLOCKS_WRITE));
215+
var destSettings = settingsResponse.getIndexToSettings().get(destIndex);
216+
217+
// sanity check
218+
assertTrue(destSettings.getAsBoolean(IndexMetadata.SETTING_BLOCKS_READ, false));
219+
220+
// override null removed
221+
assertNull(destSettings.get(IndexMetadata.SETTING_BLOCKS_WRITE));
222+
}
223+
224+
public void testRemoveIndexBlocks() throws Exception {
225+
assumeTrue("requires the migration reindex feature flag", REINDEX_DATA_STREAM_FEATURE_FLAG.isEnabled());
226+
227+
var sourceIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT);
228+
229+
var sourceSettings = Settings.builder()
230+
.put(IndexMetadata.SETTING_BLOCKS_WRITE, randomBoolean())
231+
.put(IndexMetadata.SETTING_READ_ONLY_ALLOW_DELETE, randomBoolean())
232+
.build();
233+
indicesAdmin().create(new CreateIndexRequest(sourceIndex, sourceSettings)).get();
234+
235+
var settingsOverride = Settings.builder()
236+
.put(IndexMetadata.SETTING_BLOCKS_WRITE, randomBoolean())
237+
.put(IndexMetadata.SETTING_READ_ONLY_ALLOW_DELETE, randomBoolean())
238+
.put(IndexMetadata.SETTING_BLOCKS_READ, randomBoolean())
239+
.build();
240+
241+
// create from source
242+
var destIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT);
243+
assertAcked(
244+
client().execute(
245+
CreateIndexFromSourceAction.INSTANCE,
246+
new CreateIndexFromSourceAction.Request(sourceIndex, destIndex, settingsOverride, Map.of(), true)
247+
)
248+
);
249+
250+
// assert settings overridden
251+
var settingsResponse = indicesAdmin().getSettings(new GetSettingsRequest().indices(destIndex)).actionGet();
252+
var destSettings = settingsResponse.getIndexToSettings().get(destIndex);
253+
254+
// remove block settings override both source settings and override settings
255+
assertNull(destSettings.get(IndexMetadata.SETTING_BLOCKS_WRITE));
256+
assertNull(destSettings.get(IndexMetadata.SETTING_READ_ONLY_ALLOW_DELETE));
257+
assertNull(destSettings.get(IndexMetadata.SETTING_BLOCKS_READ));
213258
}
214259

215260
public void testMappingsOverridden() {
@@ -255,7 +300,7 @@ public void testMappingsOverridden() {
255300
assertAcked(
256301
client().execute(
257302
CreateIndexFromSourceAction.INSTANCE,
258-
new CreateIndexFromSourceAction.Request(sourceIndex, destIndex, Settings.EMPTY, mappingOverride)
303+
new CreateIndexFromSourceAction.Request(sourceIndex, destIndex, Settings.EMPTY, mappingOverride, randomBoolean())
259304
)
260305
);
261306

x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceAction.java

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@ private CreateIndexFromSourceAction() {
3838
public static class Request extends ActionRequest implements IndicesRequest, ToXContent {
3939
private final String sourceIndex;
4040
private final String destIndex;
41-
private Settings settingsOverride = Settings.EMPTY;
42-
private Map<String, Object> mappingsOverride = Map.of();
41+
private Settings settingsOverride;
42+
private Map<String, Object> mappingsOverride;
43+
private boolean removeIndexBlocks;
4344
private static final ParseField SETTINGS_OVERRIDE_FIELD = new ParseField("settings_override");
4445
private static final ParseField MAPPINGS_OVERRIDE_FIELD = new ParseField("mappings_override");
46+
private static final ParseField REMOVE_INDEX_BLOCKS_FIELD = new ParseField("remove_index_blocks");
4547
private static final ObjectParser<Request, Void> PARSER = new ObjectParser<>("create_index_from_source_request");
4648

4749
static {
@@ -50,25 +52,36 @@ public static class Request extends ActionRequest implements IndicesRequest, ToX
5052
SETTINGS_OVERRIDE_FIELD,
5153
ObjectParser.ValueType.OBJECT
5254
);
53-
5455
PARSER.declareField(
5556
(parser, request, context) -> request.mappingsOverride(Map.of("_doc", parser.map())),
5657
MAPPINGS_OVERRIDE_FIELD,
5758
ObjectParser.ValueType.OBJECT
5859
);
60+
PARSER.declareField(
61+
(parser, request, context) -> request.removeIndexBlocks(parser.booleanValue()),
62+
REMOVE_INDEX_BLOCKS_FIELD,
63+
ObjectParser.ValueType.BOOLEAN
64+
);
5965
}
6066

6167
public Request(String sourceIndex, String destIndex) {
62-
this(sourceIndex, destIndex, Settings.EMPTY, Map.of());
68+
this(sourceIndex, destIndex, Settings.EMPTY, Map.of(), false);
6369
}
6470

65-
public Request(String sourceIndex, String destIndex, Settings settingsOverride, Map<String, Object> mappingsOverride) {
71+
public Request(
72+
String sourceIndex,
73+
String destIndex,
74+
Settings settingsOverride,
75+
Map<String, Object> mappingsOverride,
76+
boolean removeIndexBlocks
77+
) {
6678
Objects.requireNonNull(settingsOverride);
6779
Objects.requireNonNull(mappingsOverride);
6880
this.sourceIndex = sourceIndex;
6981
this.destIndex = destIndex;
7082
this.settingsOverride = settingsOverride;
7183
this.mappingsOverride = mappingsOverride;
84+
this.removeIndexBlocks = removeIndexBlocks;
7285
}
7386

7487
@SuppressWarnings("unchecked")
@@ -78,6 +91,7 @@ public Request(StreamInput in) throws IOException {
7891
this.destIndex = in.readString();
7992
this.settingsOverride = Settings.readSettingsFromStream(in);
8093
this.mappingsOverride = (Map<String, Object>) in.readGenericValue();
94+
this.removeIndexBlocks = in.readBoolean();
8195
}
8296

8397
@Override
@@ -87,6 +101,7 @@ public void writeTo(StreamOutput out) throws IOException {
87101
out.writeString(destIndex);
88102
settingsOverride.writeTo(out);
89103
out.writeGenericValue(mappingsOverride);
104+
out.writeBoolean(removeIndexBlocks);
90105
}
91106

92107
@Override
@@ -110,6 +125,10 @@ public Map<String, Object> mappingsOverride() {
110125
return mappingsOverride;
111126
}
112127

128+
public boolean removeIndexBlocks() {
129+
return removeIndexBlocks;
130+
}
131+
113132
public void settingsOverride(Settings settingsOverride) {
114133
this.settingsOverride = settingsOverride;
115134
}
@@ -118,6 +137,10 @@ public void mappingsOverride(Map<String, Object> mappingsOverride) {
118137
this.mappingsOverride = mappingsOverride;
119138
}
120139

140+
public void removeIndexBlocks(boolean removeIndexBlocks) {
141+
this.removeIndexBlocks = removeIndexBlocks;
142+
}
143+
121144
public void fromXContent(XContentParser parser) throws IOException {
122145
PARSER.parse(parser, this, null);
123146
}
@@ -136,6 +159,7 @@ public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params par
136159
settingsOverride.toXContent(builder, params);
137160
builder.endObject();
138161
}
162+
builder.field(REMOVE_INDEX_BLOCKS_FIELD.getPreferredName(), removeIndexBlocks);
139163

140164
return builder;
141165
}
@@ -148,12 +172,14 @@ public boolean equals(Object o) {
148172
return Objects.equals(sourceIndex, request.sourceIndex)
149173
&& Objects.equals(destIndex, request.destIndex)
150174
&& Objects.equals(settingsOverride, request.settingsOverride)
151-
&& Objects.equals(mappingsOverride, request.mappingsOverride);
175+
&& Objects.equals(mappingsOverride, request.mappingsOverride)
176+
&& removeIndexBlocks == request.removeIndexBlocks;
177+
152178
}
153179

154180
@Override
155181
public int hashCode() {
156-
return Objects.hash(sourceIndex, destIndex, settingsOverride, mappingsOverride);
182+
return Objects.hash(sourceIndex, destIndex, settingsOverride, mappingsOverride, removeIndexBlocks);
157183
}
158184

159185
@Override

x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceTransportAction.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ public class CreateIndexFromSourceTransportAction extends HandledTransportAction
4646
private final ClusterService clusterService;
4747
private final Client client;
4848
private final IndexScopedSettings indexScopedSettings;
49+
private static final Settings REMOVE_INDEX_BLOCKS_SETTING_OVERRIDE = Settings.builder()
50+
.putNull(IndexMetadata.SETTING_READ_ONLY)
51+
.putNull(IndexMetadata.SETTING_READ_ONLY_ALLOW_DELETE)
52+
.putNull(IndexMetadata.SETTING_BLOCKS_WRITE)
53+
.putNull(IndexMetadata.SETTING_BLOCKS_METADATA)
54+
.putNull(IndexMetadata.SETTING_BLOCKS_READ)
55+
.build();
4956

5057
@Inject
5158
public CreateIndexFromSourceTransportAction(
@@ -80,12 +87,15 @@ protected void doExecute(Task task, CreateIndexFromSourceAction.Request request,
8087

8188
logger.debug("Creating destination index [{}] for source index [{}]", request.destIndex(), request.sourceIndex());
8289

83-
Settings settings = Settings.builder()
84-
// add source settings
90+
Settings.Builder settings = Settings.builder()
91+
// first settings from source index
8592
.put(filterSettings(sourceIndex))
86-
// add override settings from request
87-
.put(request.settingsOverride())
88-
.build();
93+
// then override with request settings
94+
.put(request.settingsOverride());
95+
if (request.removeIndexBlocks()) {
96+
// lastly, override with settings to remove index blocks if requested
97+
settings.put(REMOVE_INDEX_BLOCKS_SETTING_OVERRIDE);
98+
}
8999

90100
Map<String, Object> mergeMappings;
91101
try {

x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamIndexTransportAction.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,21 +192,17 @@ private void createIndex(
192192
) {
193193
logger.debug("Creating destination index [{}] for source index [{}]", destIndexName, sourceIndex.getIndex().getName());
194194

195-
var removeReadOnlyOverride = Settings.builder()
196-
// remove read-only settings if they exist
197-
.putNull(IndexMetadata.SETTING_READ_ONLY)
198-
.putNull(IndexMetadata.SETTING_READ_ONLY_ALLOW_DELETE)
199-
.putNull(IndexMetadata.SETTING_BLOCKS_WRITE)
200-
// settings to optimize reindex
195+
var settingsOverride = Settings.builder()
201196
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
202197
.put(IndexSettings.INDEX_REFRESH_INTERVAL_SETTING.getKey(), -1)
203198
.build();
204199

205200
var request = new CreateIndexFromSourceAction.Request(
206201
sourceIndex.getIndex().getName(),
207202
destIndexName,
208-
removeReadOnlyOverride,
209-
Map.of()
203+
settingsOverride,
204+
Map.of(),
205+
true
210206
);
211207
request.setParentTask(parentTaskId);
212208
var errorMessage = String.format(Locale.ROOT, "Could not create index [%s]", request.destIndex());

x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/action/CreateFromSourceIndexRequestTests.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ protected Request createTestInstance() {
6363
if (randomBoolean()) {
6464
return new Request(source, dest);
6565
} else {
66-
return new Request(source, dest, randomSettings(), randomMappings());
66+
return new Request(source, dest, randomSettings(), randomMappings(), randomBoolean());
6767
}
6868
}
6969

@@ -74,14 +74,16 @@ protected Request mutateInstance(Request instance) throws IOException {
7474
String destIndex = instance.destIndex();
7575
Settings settingsOverride = instance.settingsOverride();
7676
Map<String, Object> mappingsOverride = instance.mappingsOverride();
77+
boolean removeIndexBlocks = instance.removeIndexBlocks();
7778

78-
switch (between(0, 3)) {
79+
switch (between(0, 4)) {
7980
case 0 -> sourceIndex = randomValueOtherThan(sourceIndex, () -> randomAlphaOfLength(30));
8081
case 1 -> destIndex = randomValueOtherThan(destIndex, () -> randomAlphaOfLength(30));
8182
case 2 -> settingsOverride = randomValueOtherThan(settingsOverride, CreateFromSourceIndexRequestTests::randomSettings);
8283
case 3 -> mappingsOverride = randomValueOtherThan(mappingsOverride, CreateFromSourceIndexRequestTests::randomMappings);
84+
case 4 -> removeIndexBlocks = removeIndexBlocks == false;
8385
}
84-
return new Request(sourceIndex, destIndex, settingsOverride, mappingsOverride);
86+
return new Request(sourceIndex, destIndex, settingsOverride, mappingsOverride, removeIndexBlocks);
8587
}
8688

8789
public static Map<String, Object> randomMappings() {

x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/migrate/30_create_from.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,39 @@ teardown:
119119
- match: {dest-index-1.mappings.properties.foo.type: boolean}
120120
- match: {dest-index-1.mappings.properties.baz.type: integer}
121121

122+
---
123+
"Test create_from with remove_index_blocks":
124+
- requires:
125+
reason: "migration reindex is behind a feature flag"
126+
test_runner_features: [capabilities]
127+
capabilities:
128+
- method: POST
129+
path: /_migration/reindex
130+
capabilities: [migration_reindex]
131+
- do:
132+
indices.create:
133+
index: source-index-1
134+
body:
135+
settings:
136+
index:
137+
blocks.write: true
138+
blocks.read: true
139+
number_of_shards: 1
140+
number_of_replicas: 0
141+
- do:
142+
migrate.create_from:
143+
source: "source-index-1"
144+
dest: "dest-index-1"
145+
body:
146+
settings_override:
147+
index:
148+
blocks.write: false
149+
blocks.read: true
150+
remove_index_blocks: true
151+
- do:
152+
indices.get_settings:
153+
index: dest-index-1
154+
- match: { dest-index-1.settings.index.number_of_shards: "1" }
155+
- match: { dest-index-1.settings.index.blocks.write: null }
156+
- match: { dest-index-1.settings.index.blocks.read: null }
157+

0 commit comments

Comments
 (0)