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

Return 404 error if perform an action against a non existent Physical Server #202

Merged
merged 1 commit into from
Dec 18, 2017

Conversation

douglasgabriel
Copy link
Member

This PR is able to:

  • Fix the error that returns a 200 code if try to perform an action against a non existent PH;
  • Return 404 if the ID of the Physical Server doesn't exist.

@douglasgabriel douglasgabriel changed the base branch from master to gaprindashvili November 13, 2017 12:42
@douglasgabriel douglasgabriel changed the base branch from gaprindashvili to master November 13, 2017 12:43
@douglasgabriel
Copy link
Member Author

Hi @imtayadeway @agrare, could you review this PR?

@douglasgabriel
Copy link
Member Author

@miq-bot add_label gaprindashvili/yes

@abellotti
Copy link
Member

while this might be ok for targeting a single resource, this will be incompatible with and break the behavior on bulk requests. Note that for bulk requests, we don't want to interrupt the request mid-flight and return the 404, callers won't know what was, wasn't done. The action result signature while is a 200 has the success attribute which can be queried. This allows us to complete bulk requests even if a couple of resources in the middle of the request do not exist.

@jntullo
Copy link

jntullo commented Nov 13, 2017

I agree with @abellotti. You may want to look into what has been done on delete, you may be able to do something similar to handle both scenarios if this is required.

@douglasgabriel
Copy link
Member Author

@abellotti and @jntullo I believe that with the changes on here this problem is solved, right?

@jntullo
Copy link

jntullo commented Nov 13, 2017

@douglasgabriel that update has unintended consequences to other controllers as can be seen by the Travis failures. For now, I would keep the update contained to this particular method.

@douglasgabriel
Copy link
Member Author

Sorry about that @jntullo, I fixed this

@jntullo
Copy link

jntullo commented Nov 14, 2017

@douglasgabriel can you please add tests? Thanks!

def single_resource?
!@req.json_body.key?('resources')
end

Copy link
Member

Choose a reason for hiding this comment

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

I think this method should probably go in lib/api/request_adapter.rb, WDYT @jntullo ?

Copy link

Choose a reason for hiding this comment

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

@abellotti yeah, i agree with that

Copy link
Member Author

Choose a reason for hiding this comment

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

@abellotti @jntullo Done 👍

@abellotti
Copy link
Member

LGTM. @jntullo ?

@miq-bot
Copy link
Member

miq-bot commented Nov 21, 2017

This pull request is not mergeable. Please rebase and repush.

@douglasgabriel douglasgabriel force-pushed the XCS-503 branch 2 times, most recently from 1bb94f8 to 9d0a2c4 Compare November 21, 2017 19:20
@abellotti
Copy link
Member

ping @imtayadeway @jntullo any updates needed here ?

Copy link
Contributor

@imtayadeway imtayadeway left a comment

Choose a reason for hiding this comment

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

Thanks for your effort here! This looks agreeable in general....but I think the codeclimate complaints are justified and it would be good to address that in this PR. It's also not clear why you needed to rescue error in multiple places from your single test - I think we need at least one test for every path that's described by your changes here. Thanks!

@douglasgabriel douglasgabriel force-pushed the XCS-503 branch 3 times, most recently from 2280b22 to 20d93a8 Compare December 13, 2017 13:44
Copy link
Contributor

@imtayadeway imtayadeway left a comment

Choose a reason for hiding this comment

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

@douglasgabriel thanks for your patience! It took me a while to work through. I think I can now pinpoint what I was unsure about before: this change introduces a change of behavior for all the different actions that physical servers support, but there's only one test, for one of the actions. We are going to need tests for each action, and also ensure that we have good coverage for each action in the case that we want to preserve (bulk actions always respond with 200) as a prerequisite to getting this merged.

Indeed, the only change that's required for your existing test to pass is the following:

@@ -54,6 +54,9 @@ module Api
 
     def change_resource_state(state, type, id)
       raise BadRequestError, "Must specify an id for changing a #{type} resource" unless id
+      if single_resource? && !collection_class(type).exists?(id)
+        raise NotFoundError
+      end
 
       api_action(type, id) do |klass|
         begin

And I think that might be OK, too. You'll need to add something similar to the refresh action. In a pinch, you could extract that into a private method (though try to avoid using predicate methods as guard clauses, as you have with id_present?. ensure_id_present or similar would be better). I'd recommend trying to do that instead of trying to refactor refreshes to be a kind of state change. Even though there's incidental duplication there, that's OK - a refresh is not a state change per se and the implementation might change for different reasons to the other actions.

@douglasgabriel
Copy link
Member Author

Hm, good point and good suggestion, I agree with you

@douglasgabriel
Copy link
Member Author

It's done @imtayadeway 👍

end

def ensure_resource_exists(type, id)
raise ActiveRecord::RecordNotFound if single_resource? && !collection_class(type).exists?(id)
Copy link
Member

Choose a reason for hiding this comment

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

why is this method needed ? resource_search would throw the NotFoundError plus do the necessary RBAC validation.

Copy link
Contributor

Choose a reason for hiding this comment

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

@abellotti it does, but we don't want it caught by the api_action block, which will always respond with a 200. Performing another resource_search would be unnecessarily expensive if we only want to check for existence.

@douglasgabriel you may want to use our own NotFoundError here

@@ -41,7 +41,8 @@ def restart_mgmt_controller_resource(type, id, _data)
end

def refresh_resource(type, id, _data = nil)
raise BadRequestError, "Must specify an id for refreshing a #{type} resource" unless id
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be OK not to extract this into a private method, since that alters the message to talk about "changing" here, instead of "refreshing". Again, I think it's an acceptable structural similarity.

@@ -41,7 +41,8 @@ def restart_mgmt_controller_resource(type, id, _data)
end

def refresh_resource(type, id, _data = nil)
raise BadRequestError, "Must specify an id for refreshing a #{type} resource" unless id
ensure_id_present(type, id)
ensure_resource_exists(type, id)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it may be more appropriate to say:

ensure_resource_exists(type, id) if single_request?

Since we're trying to express that we don't care if a resource exists at this point for a bulk operation, because it's handled elsewhere.

@@ -68,10 +70,6 @@ def change_resource_state(state, type, id)
end
end

def server_ident(server)
Copy link
Contributor

Choose a reason for hiding this comment

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

Was there a reason this was moved? I think it would be better to leave it here if it is not essential to fixing the bug

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, ok. it was just for code organization reason

@miq-bot
Copy link
Member

miq-bot commented Dec 15, 2017

Checked commit douglasgabriel@124743a with ruby 2.3.3, rubocop 0.47.1, haml-lint 0.20.0, and yamllint 1.10.0
2 files checked, 0 offenses detected
Everything looks fine. ⭐

Copy link
Contributor

@imtayadeway imtayadeway left a comment

Choose a reason for hiding this comment

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

Thanks @douglasgabriel for your work on this! LGTM

@douglasgabriel
Copy link
Member Author

Thank you for the support 👍

@chrisarcand chrisarcand merged commit d17fd18 into ManageIQ:master Dec 18, 2017
@chrisarcand chrisarcand assigned chrisarcand and unassigned abellotti Dec 18, 2017
simaishi pushed a commit that referenced this pull request Dec 19, 2017
Return 404 error if perform an action against a non existent Physical Server
(cherry picked from commit d17fd18)
@simaishi
Copy link
Contributor

Gaprindashvili backport details:

$ git log -1
commit a5e20f83f4b4a760e4e1b839589a3496ed17e7e2
Author: Chris Arcand <chrisarcand@users.noreply.github.com>
Date:   Mon Dec 18 08:42:29 2017 -0600

    Merge pull request #202 from douglasgabriel/XCS-503
    
    Return 404 error if perform an action against a non existent Physical Server
    (cherry picked from commit d17fd1859f46e7fb83f1ef604418efc669a3550d)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants