Skip to content

Commit

Permalink
Add more index blocks check for resize APIs (#4845) (#6774)
Browse files Browse the repository at this point in the history
* Add more index blocks check for resize APIs (#4845)

Signed-off-by: Gao Binlong <gbinlong@amazon.com>

* modify change log

Signed-off-by: Gao Binlong <gbinlong@amazon.com>

* Rewording the error message

Signed-off-by: Gao Binlong <gbinlong@amazon.com>

---------

Signed-off-by: Gao Binlong <gbinlong@amazon.com>
  • Loading branch information
gaobinlong committed May 17, 2023
1 parent 3d86418 commit 170dcef
Show file tree
Hide file tree
Showing 12 changed files with 539 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Removed

### Fixed
- Add more index blocks check for resize APIs ([#6774](https://github.com/opensearch-project/OpenSearch/pull/6774))
- Replaces ZipInputStream with ZipFile to fix Zip Slip vulnerability ([#7230](https://github.com/opensearch-project/OpenSearch/pull/7230))
- Add missing validation/parsing of SearchBackpressureMode of SearchBackpressureSettings ([#7541](https://github.com/opensearch-project/OpenSearch/pull/7541))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,99 @@ setup:
settings:
index.number_of_replicas: 0
index.number_of_shards: 6

---
"Returns error if target index's metadata write is blocked":

- skip:
version: " - 2.9.99"
reason: "only available in 3.0+"

# block source index's write operations
- do:
indices.put_settings:
index: source
body:
index.blocks.write: true
index.number_of_replicas: 0

- do:
cluster.health:
wait_for_status: green
index: source

# set `index.blocks.read_only` to `true` for target index
- do:
catch: /action_request_validation_exception/
indices.clone:
index: "source"
target: "new_cloned_index"
wait_for_active_shards: 1
cluster_manager_timeout: 10s
body:
settings:
index.number_of_replicas: 0
index.blocks.read_only: true

# set `index.blocks.metadata` to `true` for target index
- do:
catch: /action_request_validation_exception/
indices.clone:
index: "source"
target: "new_cloned_index"
wait_for_active_shards: 1
cluster_manager_timeout: 10s
body:
settings:
index.number_of_replicas: 0
index.blocks.metadata: true

# set source index's setting `index.blocks.read_only` to `true`
- do:
indices.put_settings:
index: source
body:
index.blocks.read_only: true

- do:
catch: /illegal_argument_exception/
indices.clone:
index: "source"
target: "new_cloned_index"
wait_for_active_shards: 1
cluster_manager_timeout: 10s
body:
settings:
index.number_of_replicas: 0

# overwrite the source index's setting, everything is fine
- do:
indices.clone:
index: "source"
target: "new_cloned_index"
wait_for_active_shards: 1
cluster_manager_timeout: 10s
body:
settings:
index.number_of_replicas: 0
index.blocks.read_only: null

- do:
cluster.health:
wait_for_status: green

- do:
get:
index: new_cloned_index
id: "1"

- match: { _index: new_cloned_index }
- match: { _id: "1" }
- match: { _source: { foo: "hello world" } }

# clear the source index's read_only blocks because it will block deleting index
- do:
indices.put_settings:
index: source
body:
index.blocks.read_only: null
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
---
"Shrink index via API":
setup:
# creates an index with one document solely allocated on a particular data node
# and shrinks it into a new index with a single shard
# we don't do the relocation to a single node after the index is created
# here since in a mixed version cluster we can't identify
# which node is the one with the highest version and that is the only one that can safely
# be used to shrink the index.

- skip:
features: allowed_warnings

- do:
nodes.info:
node_id: data:true
Expand All @@ -32,14 +28,10 @@
id: "1"
body: { "foo": "hello world" }

- do:
get:
index: source
id: "1"

- match: { _index: source }
- match: { _id: "1" }
- match: { _source: { foo: "hello world" } }
---
"Shrink index via API":
- skip:
features: allowed_warnings

# make it read-only
- do:
Expand Down Expand Up @@ -79,3 +71,103 @@
- match: { _index: target }
- match: { _id: "1" }
- match: { _source: { foo: "hello world" } }

---
"Returns error if target index's metadata write is blocked":

- skip:
version: " - 2.9.99"
reason: "only available in 3.0+"

# block source index's write operations
- do:
indices.put_settings:
index: source
body:
index.blocks.write: true
index.number_of_replicas: 0

- do:
cluster.health:
wait_for_status: green
index: source

# set `index.blocks.read_only` to `true` for target index
- do:
catch: /action_request_validation_exception/
indices.shrink:
index: "source"
target: "new_shrunken_index"
wait_for_active_shards: 1
cluster_manager_timeout: 10s
body:
settings:
index.number_of_replicas: 0
index.number_of_shards: 1
index.blocks.read_only: true

# set `index.blocks.metadata` to `true` for target index
- do:
catch: /action_request_validation_exception/
indices.shrink:
index: "source"
target: "new_shrunken_index"
wait_for_active_shards: 1
cluster_manager_timeout: 10s
body:
settings:
index.number_of_replicas: 0
index.number_of_shards: 1
index.blocks.metadata: true

# set source index's setting `index.blocks.read_only` to `true`
- do:
indices.put_settings:
index: source
body:
index.blocks.read_only: true

- do:
catch: /illegal_argument_exception/
indices.shrink:
index: "source"
target: "new_shrunken_index"
wait_for_active_shards: 1
cluster_manager_timeout: 10s
body:
settings:
index.number_of_replicas: 0
index.number_of_shards: 1

# overwrite the source index's setting, everything is fine
- do:
indices.shrink:
index: "source"
target: "new_shrunken_index"
wait_for_active_shards: 1
cluster_manager_timeout: 10s
body:
settings:
index.number_of_replicas: 0
index.number_of_shards: 1
index.blocks.read_only: null

- do:
cluster.health:
wait_for_status: green

- do:
get:
index: new_shrunken_index
id: "1"

- match: { _index: new_shrunken_index }
- match: { _id: "1" }
- match: { _source: { foo: "hello world" } }

# clear the source index's read_only blocks because it will block deleting index
- do:
indices.put_settings:
index: source
body:
index.blocks.read_only: null
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,103 @@ setup:
settings:
index.number_of_replicas: 0
index.number_of_shards: 6

---
"Returns error if target index's metadata write is blocked":

- skip:
version: " - 2.9.99"
reason: "only available in 3.0+"

# block source index's write operations
- do:
indices.put_settings:
index: source
body:
index.blocks.write: true
index.number_of_replicas: 0

- do:
cluster.health:
wait_for_status: green
index: source

# set `index.blocks.read_only` to `true` for target index
- do:
catch: /action_request_validation_exception/
indices.split:
index: "source"
target: "new_split_index"
wait_for_active_shards: 1
cluster_manager_timeout: 10s
body:
settings:
index.number_of_replicas: 0
index.number_of_shards: 4
index.blocks.read_only: true

# set `index.blocks.metadata` to `true` for target index
- do:
catch: /action_request_validation_exception/
indices.split:
index: "source"
target: "new_split_index"
wait_for_active_shards: 1
cluster_manager_timeout: 10s
body:
settings:
index.number_of_replicas: 0
index.number_of_shards: 4
index.blocks.metadata: true

# set source index's setting `index.blocks.read_only` to `true`
- do:
indices.put_settings:
index: source
body:
index.blocks.read_only: true

- do:
catch: /illegal_argument_exception/
indices.split:
index: "source"
target: "new_split_index"
wait_for_active_shards: 1
cluster_manager_timeout: 10s
body:
settings:
index.number_of_replicas: 0
index.number_of_shards: 4

# overwrite the source index's setting, everything is fine
- do:
indices.split:
index: "source"
target: "new_split_index"
wait_for_active_shards: 1
cluster_manager_timeout: 10s
body:
settings:
index.number_of_replicas: 0
index.number_of_shards: 4
index.blocks.read_only: null

- do:
cluster.health:
wait_for_status: green

- do:
get:
index: new_split_index
id: "1"

- match: { _index: new_split_index }
- match: { _id: "1" }
- match: { _source: { foo: "hello world" } }

# clear the source index's read_only blocks because it will block deleting index
- do:
indices.put_settings:
index: source
body:
index.blocks.read_only: null
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,27 @@ public ActionRequestValidationException validate() {
if (maxShardSize != null && maxShardSize.getBytes() <= 0) {
validationException = addValidationError("max_shard_size must be greater than 0", validationException);
}
// Check target index's settings, if `index.blocks.read_only` is `true`, the target index's metadata writes will be disabled
// and then cause the new shards to be unassigned.
if (IndexMetadata.INDEX_READ_ONLY_SETTING.get(targetIndexRequest.settings()) == true) {
validationException = addValidationError(
"target index ["
+ targetIndexRequest.index()
+ "] will be blocked by [index.blocks.read_only=true], this will disable metadata writes and cause the shards to be unassigned",
validationException
);
}

// Check target index's settings, if `index.blocks.metadata` is `true`, the target index's metadata writes will be disabled
// and then cause the new shards to be unassigned.
if (IndexMetadata.INDEX_BLOCKS_METADATA_SETTING.get(targetIndexRequest.settings()) == true) {
validationException = addValidationError(
"target index ["
+ targetIndexRequest.index()
+ "] will be blocked by [index.blocks.metadata=true], this will disable metadata writes and cause the shards to be unassigned",
validationException
);
}
assert copySettings == null || copySettings;
return validationException;
}
Expand Down
Loading

0 comments on commit 170dcef

Please sign in to comment.