Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add check for invalid index in WildcardExpressionResolver #26409

Merged
merged 14 commits into from Sep 15, 2017

Conversation

hub-cap
Copy link
Contributor

@hub-cap hub-cap commented Aug 28, 2017

Previous behavior in elasticsearch 5.x threw a 400 when accessing an
index that started with an underscore. In 6, this was changed to a 404,
an IndexNotFoundException. This is not a valid index however, and
should return the 400, as it is a bad request.

This commit adds validation to WildcardExpressionResolver
to ensure that indices cannot begin with an underscore. This change
still allows for behavior such as _foo,bar and will not mess with the
existing way we resolve indices. It will error given the example with an
InvalidIndexNameException.

This commit adds an optional override for validating a
MasterNodeRequest. Cluster state can optionally be used for validation
as well, to check the state of things such as index already existing in
the validation logic.
@hub-cap hub-cap added WIP :Core/Infra/REST API REST infrastructure and utilities labels Aug 28, 2017
@hub-cap
Copy link
Contributor Author

hub-cap commented Aug 28, 2017

I wanted to get some eyes on this to make sure that I am doing this validation properly. I saw a few different spots where validation logic existed, so I wanted to extract it out to a common place for the index actions. Feel free to tell me Im 100% off base w/ this :D

for(String index: request.indices()) {
// Create index service also does validation on the index name which does not require
// cluster state, so it does not check if things like the index already exists in the cluster
MetaDataCreateIndexService.validateIndexOrAliasName(index, InvalidIndexNameException::new);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure where you're headed, but this thing is better done in org.elasticsearch.action.admin.indices.get.GetIndexRequest#validate


@Override
protected void validateRequest(CreateIndexRequest request, ClusterState state) throws Exception {
MetaDataCreateIndexService.validateIndexName(request.index(), state);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see where you're heading with the extra state validation, but name collisions are a rare occasion and I'm not sure it's worth it to have the extra API complexity in order to fail early. If we remove that we can move the name validation to org.elasticsearch.action.admin.indices.create.CreateIndexRequest#validate

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lack of validation in one of the calls actually caused behavior to break between major versions of ES. I think we should avoid this, but I am completely fine w keeping it out of a generic place.

@hub-cap hub-cap removed the WIP label Sep 5, 2017
@hub-cap
Copy link
Contributor Author

hub-cap commented Sep 5, 2017

ok, I have updated the commit to put the assertion in the actual WildcardExpressionResolver, after a check for _all, so the validation never has to special case that. This is the least intrusive place that will ensure that these indexes will no longer return IndexNotFoundException's.

@hub-cap hub-cap changed the title Add optional validation to master node actions Add check for invalid index in WildcardExpressionResolver Sep 5, 2017
@hub-cap
Copy link
Contributor Author

hub-cap commented Sep 5, 2017

I have also updated the comment / PR name to show what I am actually trying to achieve :)

@hub-cap hub-cap requested a review from bleskes September 5, 2017 15:42
Copy link
Member

@jasontedor jasontedor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good, but I would like to see a test that would fail before this change yet would pass after this change that asserts the status here on an HTTP request would be 400. A REST test is fine for this.

@@ -601,6 +602,7 @@ boolean isPreserveAliases() {
if (Strings.isEmpty(expression)) {
throw indexNotFoundException(expression);
}
assertValidAliasOrIndex(expression);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is not an actual assertion (like assert), let's change the name.


public void testInvalidIndex() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("testXXX"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's okay to call the index "test", and to fit all of this on one line.

Copy link
Member

@martijnvg martijnvg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -641,7 +642,7 @@ public void testConcreteIndicesWildcardAndAliases() {
// when ignoreAliases option is set, concreteIndexNames resolves the provided expressions
// only against the defined indices
IndicesOptions ignoreAliasesOptions = IndicesOptions.fromOptions(false, false, true, false, true, false, true);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unneeded change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should i remove this? my intellij settings might be a bit aggressive :)

@bleskes
Copy link
Contributor

bleskes commented Sep 7, 2017

@hub-cap can you elaborate a bit as to why you went to a new direction - i.e., we don't check this in the #validate method of requests as you had before?

Copy link
Member

@jasontedor jasontedor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the test should be tighter.

@@ -160,3 +160,11 @@ setup:
- is_true: test_index_2.settings
- is_true: test_index_3.settings

---
"Should return an exception when querying invalid indices":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test needs to assert on the HTTP status.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I was unaware we could do that. I must've missed it in the docs!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might have to add a specific catch for bad_request (400).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ill block this on it being merged

@hub-cap
Copy link
Contributor Author

hub-cap commented Sep 7, 2017

can you elaborate a bit ...

@bleskes initially I did start a generic validation on all of the MasterNode actions, but this proved problematic because there was not a single place the expressions were resolved. Some subclass TransportClusterInfoAction and some do not, and that subclass handles resolving for any of its children, but other actions handle it differently. Then I realized that I didnt care about every action, and the place that is actually causing an issue is in the resolvers themselves. So i went down the path of making it generic in the resolver, so a call to GET /foo,_bar would properly fail with a 400 on _bar, rather than the 404 index not found. And so i eventually found the place that has already decided the expression is not _all, so i could remove a conditional check on "if it starts with underscore and is *not* all".

In the end, I was trying to solve a specific case (indices should not start with underscore) in a generic way in any action, rather than validating it in the place that every action uses to resolve indices.

Edit

And, the Expression Resolver was actually throwing the 404 not found, so the "Fix" would have to wrap that and fix the handling, or throw the proper exception in the resolver itself.

@bleskes
Copy link
Contributor

bleskes commented Sep 8, 2017

@hub-cap thanks for the explanation. I see the hassle of going through all relevant requests and adapt their validate() method. I'm OK with compromising and putting it deeper in the index resolver (with the hope it won't bubble up other trouble).

@hub-cap
Copy link
Contributor Author

hub-cap commented Sep 8, 2017

I think about it this way, but I am also new to the codebase, so take it with a grain of salt :)

The index resolver already throws a not found for an index that does resolve to something existing, and now it also throws an invalid index if you try to resolve a bad index.

@hub-cap
Copy link
Contributor Author

hub-cap commented Sep 15, 2017

I have changed the test to use the bad_request

Copy link
Member

@jasontedor jasontedor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@hub-cap
Copy link
Contributor Author

hub-cap commented Sep 15, 2017

@elasticmachine test this please

@hub-cap hub-cap merged commit 296c239 into elastic:master Sep 15, 2017
hub-cap added a commit that referenced this pull request Sep 15, 2017
This commit adds validation to the resolving of indexes in the wildcard
expression resolver. It no longer throws a 404 Not Found when resolving
invalid indices. It throws a 400 instead, as it is an invalid
index. This was the behavior of 5.x.
hub-cap added a commit that referenced this pull request Sep 16, 2017
This commit adds validation to the resolving of indexes in the wildcard
expression resolver. It no longer throws a 404 Not Found when resolving
invalid indices. It throws a 400 instead, as it is an invalid
index. This was the behavior of 5.x.
jasontedor added a commit to jasontedor/elasticsearch that referenced this pull request Sep 16, 2017
* master:
  fix testSniffNodes to use the new error message
  Add check for invalid index in WildcardExpressionResolver (elastic#26409)
  Docs: Use single-node discovery.type for dev example
  Filter unsupported relation for range query builder (elastic#26620)
  Fix kuromoji default stoptags (elastic#26600)
  [Docs] Add description for missing fields in Reindex/Update/Delete By Query (elastic#26618)
  [Docs] Update ingest.asciidoc (elastic#26599)
  Better message text for ResponseException
  [DOCS] Remove edit link from ML node
  enable bwc testing
  fix StartRecoveryRequestTests.testSerialization
  Add bad_request to the rest-api-spec catch params (elastic#26539)
  Introduce a History UUID as a requirement for ops based recovery  (elastic#26577)
  Add missing catch arguments to the rest api spec (elastic#26536)
jasontedor added a commit to droberts195/elasticsearch that referenced this pull request Sep 19, 2017
* master: (278 commits)
  Move pre-6.0 node checkpoint to SequenceNumbers
  Invalid JSON request body caused endless loop (elastic#26680)
  added comment
  fix line length violation
  Moved the check to fetch phase. This basically means that we throw a better error message instead of an AOBE and not adding more restrictions.
  inner hits: Do not allow inner hits that use _source and have a non nested object field as parent
  Separate Painless Whitelist Loading from the Painless Definition (elastic#26540)
  convert more admin requests to writeable (elastic#26566)
  Handle release of 5.6.1
  Allow `InputStreamStreamInput` array size validation where applicable (elastic#26692)
  Update global checkpoint with permit after recovery
  Filter pre-6.0 nodes for checkpoint invariants
  Skip bad request REST test on pre-6.0
  Reenable BWC tests after disabling for backport
  Add global checkpoint tracking on the primary
  [Test] Fix reference/cat/allocation/line_8 test failure
  [Docs] improved description for fs.total.available_in_bytes (elastic#26657)
  Fix discovery-file plugin to use custom config path
  fix testSniffNodes to use the new error message
  Add check for invalid index in WildcardExpressionResolver (elastic#26409)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Core/Infra/REST API REST infrastructure and utilities
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants