diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/cat.aliases.json b/rest-api-spec/src/main/resources/rest-api-spec/api/cat.aliases.json index d37273cfd41bf..6ee594b099c43 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/cat.aliases.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/cat.aliases.json @@ -53,6 +53,18 @@ "type":"boolean", "description":"Verbose mode. Display column headers", "default":false + }, + "expand_wildcards":{ + "type":"enum", + "options":[ + "open", + "closed", + "hidden", + "none", + "all" + ], + "default": ["all"], + "description":"Whether to expand wildcard expression to concrete indices that are open, closed or both." } } } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/cat.indices.json b/rest-api-spec/src/main/resources/rest-api-spec/api/cat.indices.json index 76c749cc7d3bd..d4a7eb3b051d2 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/cat.indices.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/cat.indices.json @@ -107,6 +107,18 @@ "type":"boolean", "description":"If set to true segment stats will include stats for segments that are not currently loaded into memory", "default":false + }, + "expand_wildcards":{ + "type":"enum", + "options":[ + "open", + "closed", + "hidden", + "none", + "all" + ], + "default": "all", + "description":"Whether to expand wildcard expression to concrete indices that are open, closed or both." } } } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/cluster.health.json b/rest-api-spec/src/main/resources/rest-api-spec/api/cluster.health.json index 7911a8e244218..2a21ff3725b6a 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/cluster.health.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/cluster.health.json @@ -33,6 +33,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/cluster.state.json b/rest-api-spec/src/main/resources/rest-api-spec/api/cluster.state.json index d6f0e9ababc6d..017705082d189 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/cluster.state.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/cluster.state.json @@ -97,6 +97,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/count.json b/rest-api-spec/src/main/resources/rest-api-spec/api/count.json index 2e19bee5250f9..9f6461b16d3eb 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/count.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/count.json @@ -69,6 +69,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/delete_by_query.json b/rest-api-spec/src/main/resources/rest-api-spec/api/delete_by_query.json index 69b20cb10408e..c840c763f4d90 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/delete_by_query.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/delete_by_query.json @@ -79,10 +79,16 @@ "description" : "What to do when the delete by query hits version conflicts?" }, "expand_wildcards": { - "type" : "enum", - "options" : ["open","closed","none","all"], - "default" : "open", - "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both." + "type" : "enum", + "options" : [ + "open", + "closed", + "hidden", + "none", + "all" + ], + "default" : "open", + "description" :"Whether to expand wildcard expression to concrete indices that are open, closed or both." }, "lenient": { "type" : "boolean", diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/field_caps.json b/rest-api-spec/src/main/resources/rest-api-spec/api/field_caps.json index eed6f8bf082a2..d56c3313a0bf0 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/field_caps.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/field_caps.json @@ -47,6 +47,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.clear_cache.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.clear_cache.json index b1b1d8214c47d..64c10a520c7c4 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.clear_cache.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.clear_cache.json @@ -53,6 +53,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.close.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.close.json index 539088199d683..f26c8e77a06a6 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.close.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.close.json @@ -43,6 +43,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.delete.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.delete.json index d77d47f0d739b..53fdf44bb36a1 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.delete.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.delete.json @@ -43,6 +43,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.exists.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.exists.json index d6bdcef95815f..7539f44a81eed 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.exists.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.exists.json @@ -39,6 +39,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.exists_alias.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.exists_alias.json index a19786a7938f9..66e5ce92cbbe5 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.exists_alias.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.exists_alias.json @@ -51,6 +51,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.exists_type.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.exists_type.json index 2a09d8bdfa679..c854d0e8fd841 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.exists_type.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.exists_type.json @@ -39,6 +39,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.flush.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.flush.json index 1eada8f831db6..35138b920466f 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.flush.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.flush.json @@ -51,6 +51,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.forcemerge.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.forcemerge.json index 5eaf62840d841..6036b75bb83e4 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.forcemerge.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.forcemerge.json @@ -45,6 +45,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get.json index 20f243c2b595f..f78b410f5b489 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get.json @@ -43,6 +43,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_alias.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_alias.json index 800ea8d30d68d..e238c4fc38afc 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_alias.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_alias.json @@ -69,10 +69,11 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], - "default":"all", + "default": ["all"], "description":"Whether to expand wildcard expression to concrete indices that are open, closed or both." }, "local":{ diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_field_mapping.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_field_mapping.json index 449754fcd405c..15cc48a582cc4 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_field_mapping.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_field_mapping.json @@ -105,6 +105,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_mapping.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_mapping.json index 313e5cff7d20f..188203dc13664 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_mapping.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_mapping.json @@ -83,6 +83,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_settings.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_settings.json index c19fa3bf5262f..4a1dea974f750 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_settings.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_settings.json @@ -73,6 +73,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_upgrade.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_upgrade.json index 981478b41fecc..472a90121fd2a 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_upgrade.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_upgrade.json @@ -41,6 +41,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.open.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.open.json index 14050d626df83..1dab468ce4ff4 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.open.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.open.json @@ -43,6 +43,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.put_mapping.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.put_mapping.json index 03a553e758421..deb7bb728f733 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.put_mapping.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.put_mapping.json @@ -189,6 +189,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.put_settings.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.put_settings.json index 75bf3a340c311..66fe23bab8ba2 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.put_settings.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.put_settings.json @@ -53,6 +53,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.refresh.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.refresh.json index 7eee4eeec5fd0..950e0a62489fa 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.refresh.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.refresh.json @@ -43,6 +43,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.segments.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.segments.json index b99b19799dab9..83430a9a85600 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.segments.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.segments.json @@ -41,6 +41,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.shard_stores.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.shard_stores.json index b397963f99d2f..7e48e99916171 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.shard_stores.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.shard_stores.json @@ -51,6 +51,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.stats.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.stats.json index 0940313154a74..0a8960f2f9e89 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.stats.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.stats.json @@ -137,6 +137,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.upgrade.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.upgrade.json index 7cdf098e7c617..670d3e0a33586 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.upgrade.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.upgrade.json @@ -37,6 +37,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.validate_query.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.validate_query.json index 5ff6f073b77ec..3becec003a9e6 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.validate_query.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.validate_query.json @@ -69,6 +69,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/rank_eval.json b/rest-api-spec/src/main/resources/rest-api-spec/api/rank_eval.json index c87b850ab148f..eadf240192394 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/rank_eval.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/rank_eval.json @@ -43,6 +43,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/search.json b/rest-api-spec/src/main/resources/rest-api-spec/api/search.json index c93eb97f9c6ae..e5e85f21e20a4 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/search.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/search.json @@ -107,6 +107,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/search_shards.json b/rest-api-spec/src/main/resources/rest-api-spec/api/search_shards.json index 70ee592520be9..74b7055b4c4b0 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/search_shards.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/search_shards.json @@ -55,6 +55,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/search_template.json b/rest-api-spec/src/main/resources/rest-api-spec/api/search_template.json index 15409ec6c312e..00bd09729c908 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/search_template.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/search_template.json @@ -65,6 +65,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/update_by_query.json b/rest-api-spec/src/main/resources/rest-api-spec/api/update_by_query.json index 72c0f6cfad407..eb4c7ea258b3b 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/update_by_query.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/update_by_query.json @@ -89,6 +89,7 @@ "options":[ "open", "closed", + "hidden", "none", "all" ], diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cat.aliases/40_hidden.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/cat.aliases/40_hidden.yml new file mode 100644 index 0000000000000..3aa7fdbb1f760 --- /dev/null +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cat.aliases/40_hidden.yml @@ -0,0 +1,147 @@ +--- +"Test cat aliases output with a hidden index with a hidden alias": + - skip: + version: "- 7.6.99" + reason: "hidden indices and aliases were added in 7.7.0" + + - do: + indices.create: + index: test + body: + settings: + number_of_shards: "1" + number_of_replicas: "0" + index: + hidden: true + aliases: + test_alias: + is_hidden: true + + - do: + cat.aliases: {} + + - match: + $body: | + /^ + test_alias \s+ + test \s+ + - \s+ + - \s+ + - \s+ + - \s+ + $/ + + - do: + cat.aliases: + name: test_alias + + - match: + $body: | + /^ + test_alias \s+ + test \s+ + - \s+ + - \s+ + - \s+ + - \s+ + $/ + + + - do: + cat.aliases: + expand_wildcards: ["open","closed"] + + - match: + $body: | + /^ + $/ +--- +"Test cat aliases output with a hidden index with a visible alias": + - skip: + version: "- 7.6.99" + reason: "hidden indices and aliases were added in 7.7.0" + + - do: + indices.create: + index: test + body: + settings: + number_of_shards: "1" + number_of_replicas: "0" + index: + hidden: true + aliases: + test_alias: {} + - do: + cat.aliases: {} + + - match: + $body: | + /^ + test_alias \s+ + test \s+ + - \s+ + - \s+ + - \s+ + - \s+ + $/ + + - do: + cat.aliases: + name: test_alias + + - match: + $body: | + /^ + test_alias \s+ + test \s+ + - \s+ + - \s+ + - \s+ + - \s+ + $/ + +--- +"Test cat aliases output with a visible index with a hidden alias": + - skip: + version: "- 7.6.99" + reason: "hidden indices and aliases were added in 7.7.0" + + - do: + indices.create: + index: test + body: + settings: + number_of_shards: "1" + number_of_replicas: "0" + aliases: + test_alias: + is_hidden: true + - do: + cat.aliases: {} + + - match: + $body: | + /^ + test_alias \s+ + test \s+ + - \s+ + - \s+ + - \s+ + - \s+ + $/ + + - do: + cat.aliases: + name: test_alias + + - match: + $body: | + /^ + test_alias \s+ + test \s+ + - \s+ + - \s+ + - \s+ + - \s+ + $/ diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cat.indices/20_hidden.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/cat.indices/20_hidden.yml new file mode 100644 index 0000000000000..7a8cf51d4a129 --- /dev/null +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cat.indices/20_hidden.yml @@ -0,0 +1,240 @@ +--- +"Test cat indices output for hidden index": + - skip: + version: "- 7.6.99" + reason: "hidden indices were added in 7.7.0" + + - do: + indices.create: + index: index1 + body: + settings: + number_of_shards: "1" + number_of_replicas: "0" + index: + hidden: true + - do: + cat.indices: {} + - match: + $body: | + /^$/ + + - do: + cat.indices: + expand_wildcards: ["all"] + - match: + $body: | + /^(green \s+ + open \s+ + index1 \s+ + ([a-zA-Z0-9=/_+]|[\\\-]){22} \s+ + 1 \s+ + 0 \s+ + 0 \s+ + 0 \s+ + (\d+|\d+[.]\d+)(kb|b) \s+ + (\d+|\d+[.]\d+)(kb|b) \s* + ) + $/ + +--- +"Test cat indices output for dot-hidden index and dot-prefixed pattern": + - skip: + version: "- 7.6.99" + reason: "hidden indices were added in 7.7.0" + + - do: + indices.create: + index: .index1 + body: + settings: + number_of_shards: "1" + number_of_replicas: "0" + index: + hidden: true + - do: + cat.indices: {} + - match: + $body: | + /^$/ + + - do: + cat.indices: + index: ".*" + - match: + $body: | + /^(green \s+ + open \s+ + \.index1 \s+ + ([a-zA-Z0-9=/_+]|[\\\-]){22} \s+ + 1 \s+ + 0 \s+ + 0 \s+ + 0 \s+ + (\d+|\d+[.]\d+)(kb|b) \s+ + (\d+|\d+[.]\d+)(kb|b) \s* + ) + $/ + +--- +"Test cat indices output with a hidden index with a visible alias": + - skip: + version: "- 7.6.99" + reason: "hidden indices were added in 7.7.0" + + - do: + indices.create: + index: index1 + body: + settings: + number_of_shards: "1" + number_of_replicas: "0" + index: + hidden: true + aliases: + alias1: {} + - do: + cat.indices: + index: "i*" + # Can't use a bare wildcard here because Security replaces wildcards + # it with all matching authorized indices/aliases, including the visible + # alias + - match: + $body: | + /^$/ + + - do: + cat.indices: + expand_wildcards: ["open", "hidden"] + - match: + $body: | + /^(green \s+ + open \s+ + index1 \s+ + ([a-zA-Z0-9=/_+]|[\\\-]){22} \s+ + 1 \s+ + 0 \s+ + 0 \s+ + 0 \s+ + (\d+|\d+[.]\d+)(kb|b) \s+ + (\d+|\d+[.]\d+)(kb|b) \s* + ) + $/ + + - do: + cat.indices: + index: alias1 + - match: + $body: | + /^(green \s+ + open \s+ + index1 \s+ + ([a-zA-Z0-9=/_+]|[\\\-]){22} \s+ + 1 \s+ + 0 \s+ + 0 \s+ + 0 \s+ + (\d+|\d+[.]\d+)(kb|b) \s+ + (\d+|\d+[.]\d+)(kb|b) \s* + ) + $/ +--- +"Test cat indices output with a hidden index with a hidden alias": + - skip: + version: "- 7.6.99" + reason: "hidden indices and aliases were added in 7.7.0" + + - do: + indices.create: + index: index1 + body: + settings: + number_of_shards: "1" + number_of_replicas: "0" + index: + hidden: true + aliases: + alias1: + is_hidden: true + - do: + cat.indices: {} + + - match: + $body: | + /^$/ + + - do: + cat.indices: + expand_wildcards: ["all"] + - match: + $body: | + /^(green \s+ + open \s+ + index1 \s+ + ([a-zA-Z0-9=/_+]|[\\\-]){22} \s+ + 1 \s+ + 0 \s+ + 0 \s+ + 0 \s+ + (\d+|\d+[.]\d+)(kb|b) \s+ + (\d+|\d+[.]\d+)(kb|b) \s* + ) + $/ + + - do: + cat.indices: + index: alias1 + - match: + $body: | + /^(green \s+ + open \s+ + index1 \s+ + ([a-zA-Z0-9=/_+]|[\\\-]){22} \s+ + 1 \s+ + 0 \s+ + 0 \s+ + 0 \s+ + (\d+|\d+[.]\d+)(kb|b) \s+ + (\d+|\d+[.]\d+)(kb|b) \s* + ) + $/ +--- +"Test cat indices output with a hidden index, dot-hidden alias and dot pattern": + - skip: + version: "- 7.6.99" + reason: "hidden indices and aliases were added in 7.7.0" + + - do: + indices.create: + index: index1 + body: + settings: + number_of_shards: "1" + number_of_replicas: "0" + index: + hidden: true + aliases: + .alias1: + is_hidden: true + - do: + cat.indices: {} + - match: + $body: | + /^$/ + - do: + cat.indices: + index: ".*" + - match: + $body: | + /^(green \s+ + open \s+ + index1 \s+ + ([a-zA-Z0-9=/_+]|[\\\-]){22} \s+ + 1 \s+ + 0 \s+ + 0 \s+ + 0 \s+ + (\d+|\d+[.]\d+)(kb|b) \s+ + (\d+|\d+[.]\d+)(kb|b) \s* + ) + $/ diff --git a/server/src/main/java/org/elasticsearch/rest/action/cat/RestAliasAction.java b/server/src/main/java/org/elasticsearch/rest/action/cat/RestAliasAction.java index cc96487fd45dc..b66967531facd 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/cat/RestAliasAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/cat/RestAliasAction.java @@ -21,6 +21,7 @@ import com.carrotsearch.hppc.cursors.ObjectObjectCursor; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; +import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.common.Strings; @@ -54,6 +55,7 @@ protected RestChannelConsumer doCatRequest(final RestRequest request, final Node final GetAliasesRequest getAliasesRequest = request.hasParam("alias") ? new GetAliasesRequest(Strings.commaDelimitedListToStringArray(request.param("alias"))) : new GetAliasesRequest(); + getAliasesRequest.indicesOptions(IndicesOptions.fromRequest(request, getAliasesRequest.indicesOptions())); getAliasesRequest.local(request.paramAsBoolean("local", getAliasesRequest.local())); return channel -> client.admin().indices().getAliases(getAliasesRequest, new RestResponseListener(channel) { diff --git a/server/src/main/java/org/elasticsearch/rest/action/cat/RestIndicesAction.java b/server/src/main/java/org/elasticsearch/rest/action/cat/RestIndicesAction.java index e0f0e7f1f793f..5d5c792d24da4 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/cat/RestIndicesAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/cat/RestIndicesAction.java @@ -91,7 +91,7 @@ protected void documentation(StringBuilder sb) { @Override public RestChannelConsumer doCatRequest(final RestRequest request, final NodeClient client) { final String[] indices = Strings.splitStringByCommaToArray(request.param("index")); - final IndicesOptions indicesOptions = IndicesOptions.strictExpand(); + final IndicesOptions indicesOptions = IndicesOptions.fromRequest(request, IndicesOptions.strictExpand()); final boolean local = request.paramAsBoolean("local", false); final TimeValue masterNodeTimeout = request.paramAsTime("master_timeout", DEFAULT_MASTER_NODE_TIMEOUT); final boolean includeUnloadedSegments = request.paramAsBoolean("include_unloaded_segments", false); @@ -110,6 +110,12 @@ public void onResponse(final GetSettingsResponse getSettingsResponse) { final GroupedActionListener groupedListener = createGroupedListener(request, 4, listener); groupedListener.onResponse(getSettingsResponse); + // The list of indices that will be returned is determined by the indices returned from the Get Settings call. + // All the other requests just provide additional detail, and wildcards may be resolved differently depending on the + // type of request in the presence of security plugins (looking at you, ClusterHealthRequest), so + // force the IndicesOptions for all the sub-requests to be as inclusive as possible. + final IndicesOptions subRequestIndicesOptions = IndicesOptions.lenientExpandHidden(); + // Indices that were successfully resolved during the get settings request might be deleted when the subsequent cluster // state, cluster health and indices stats requests execute. We have to distinguish two cases: // 1) the deleted index was explicitly passed as parameter to the /_cat/indices request. In this case we want the @@ -118,11 +124,11 @@ public void onResponse(final GetSettingsResponse getSettingsResponse) { // fail on the deleted index (as we want to ignore wildcards that cannot be resolved). // This behavior can be ensured by letting the cluster state, cluster health and indices stats requests re-resolve the // index names with the same indices options that we used for the initial cluster state request (strictExpand). - sendIndicesStatsRequest(indices, indicesOptions, includeUnloadedSegments, client, + sendIndicesStatsRequest(indices, subRequestIndicesOptions, includeUnloadedSegments, client, ActionListener.wrap(groupedListener::onResponse, groupedListener::onFailure)); - sendClusterStateRequest(indices, indicesOptions, local, masterNodeTimeout, client, + sendClusterStateRequest(indices, subRequestIndicesOptions, local, masterNodeTimeout, client, ActionListener.wrap(groupedListener::onResponse, groupedListener::onFailure)); - sendClusterHealthRequest(indices, indicesOptions, local, masterNodeTimeout, client, + sendClusterHealthRequest(indices, subRequestIndicesOptions, local, masterNodeTimeout, client, ActionListener.wrap(groupedListener::onResponse, groupedListener::onFailure)); } diff --git a/x-pack/plugin/build.gradle b/x-pack/plugin/build.gradle index 5425aeea03484..8691028e79bfe 100644 --- a/x-pack/plugin/build.gradle +++ b/x-pack/plugin/build.gradle @@ -158,7 +158,9 @@ testClusters.integTest { keystore 'xpack.security.transport.ssl.secure_key_passphrase', 'testnode' user username: "x_pack_rest_user", password: "x-pack-test-password" + user username: "cat_test_user", password: "cat-test-password", role: "cat_test_role" extraConfigFile nodeKey.name, nodeKey extraConfigFile nodeCert.name, nodeCert + extraConfigFile 'roles.yml', file('src/test/resources/roles.yml') } diff --git a/x-pack/plugin/src/test/java/org/elasticsearch/xpack/test/rest/CatIndicesWithSecurityIT.java b/x-pack/plugin/src/test/java/org/elasticsearch/xpack/test/rest/CatIndicesWithSecurityIT.java new file mode 100644 index 0000000000000..ab9171b7bc064 --- /dev/null +++ b/x-pack/plugin/src/test/java/org/elasticsearch/xpack/test/rest/CatIndicesWithSecurityIT.java @@ -0,0 +1,127 @@ +/* + * + * * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * * or more contributor license agreements. Licensed under the Elastic License; + * * you may not use this file except in compliance with the Elastic License. + * + */ + +package org.elasticsearch.xpack.test.rest; + +import org.apache.http.util.EntityUtils; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.Response; +import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.elasticsearch.test.SecuritySettingsSourceField; +import org.elasticsearch.test.rest.ESRestTestCase; + +import java.io.IOException; + +import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; +import static org.hamcrest.Matchers.matchesRegex; + +public class CatIndicesWithSecurityIT extends ESRestTestCase { + @Override + protected Settings restAdminSettings() { + String token = basicAuthHeaderValue("x_pack_rest_user", SecuritySettingsSourceField.TEST_PASSWORD_SECURE_STRING); + return Settings.builder() + .put(ThreadContext.PREFIX + ".Authorization", token) + .build(); + } + + @Override + protected Settings restClientSettings() { + String token = basicAuthHeaderValue("cat_test_user", new SecureString("cat-test-password".toCharArray())); + return Settings.builder() + .put(ThreadContext.PREFIX + ".Authorization", token) + .build(); + } + + public void testHiddenIndexWithVisibleAlias() throws IOException { + // Create the index and alias + { + final Request createRequest = new Request("PUT", ".index_hidden"); + createRequest.setJsonEntity( + "{\"settings\": {\"index.hidden\": true, \"number_of_replicas\": 0}, \"aliases\": {\"index_allowed\": {}}}"); + final Response createResponse = adminClient().performRequest(createRequest); + assertOK(createResponse); + ensureGreen("index_allowed"); + } + + // And it should be visible by a user that has permissions for only the alias + { + final Request catRequest = new Request("GET", "_cat/indices?format=txt"); + final Response catResponse = client().performRequest(catRequest); + assertOK(catResponse); + + final String resp = EntityUtils.toString(catResponse.getEntity()); + assertThat(resp, matchesRegex("(?s)^?green\\s+open\\s+\\.index_hidden.*$")); + } + } + + public void testHiddenIndexWithHiddenAlias() throws IOException { + // Create the index and alias + { + final Request createRequest = new Request("PUT", ".index_hidden"); + createRequest.setJsonEntity("{\"settings\": {\"index.hidden\": true, \"number_of_replicas\": 0}, " + + "\"aliases\": {\"index_allowed\": {\"is_hidden\": true}}}"); + final Response createResponse = adminClient().performRequest(createRequest); + assertOK(createResponse); + ensureGreen("index_allowed"); + } + + // It should *not* be visible + { + final Request catRequest = new Request("GET", "_cat/indices?format=txt"); + final Response catResponse = client().performRequest(catRequest); + assertOK(catResponse); + + final String resp = EntityUtils.toString(catResponse.getEntity()); + assertThat(resp, matchesRegex("(?s)\\W*")); // Should have no text + } + + // But we should be able to see the index if we ask for hidden things + { + final Request catRequest = new Request("GET", "_cat/indices?format=txt&expand_wildcards=all,hidden"); + final Response catResponse = client().performRequest(catRequest); + assertOK(catResponse); + + final String resp = EntityUtils.toString(catResponse.getEntity()); + assertThat(resp, matchesRegex("(?s)^?green\\s+open\\s+\\.index_hidden.*$")); + } + } + + public void testVisibleIndexWithHiddenAlias() throws IOException { + // Create the index and alias + { + final Request createRequest = new Request("PUT", "visible_index"); + createRequest.setJsonEntity("{\"settings\": {\"number_of_replicas\": 0}, " + + "\"aliases\": {\"index_allowed\": {\"is_hidden\": true}}}"); + final Response createResponse = adminClient().performRequest(createRequest); + assertOK(createResponse); + ensureGreen("index_allowed"); + } + + // It should *not* be visible, because this user only has access through the *hidden* alias + { + final Request catRequest = new Request("GET", "_cat/indices?format=txt"); + final Response catResponse = client().performRequest(catRequest); + assertOK(catResponse); + + final String resp = EntityUtils.toString(catResponse.getEntity()); + assertThat(resp, matchesRegex("(?s)\\W*")); // Should have no text + } + + // But we should be able to see the index if we ask for hidden things + { + final Request catRequest = new Request("GET", "_cat/indices?format=txt&expand_wildcards=all,hidden"); + final Response catResponse = client().performRequest(catRequest); + assertOK(catResponse); + + final String resp = EntityUtils.toString(catResponse.getEntity()); + assertThat(resp, matchesRegex("(?s)^?green\\s+open\\s+visible_index.*$")); + } + } +} diff --git a/x-pack/plugin/src/test/resources/roles.yml b/x-pack/plugin/src/test/resources/roles.yml new file mode 100644 index 0000000000000..5f8677860d079 --- /dev/null +++ b/x-pack/plugin/src/test/resources/roles.yml @@ -0,0 +1,7 @@ +# Required for CatIndicesWithSecurityIT +cat_test_role: + cluster: + - monitor + indices: + - names: [ "index_allowed" ] + privileges: [ "read", "write", "monitor" ]