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

Improve error message for prepare step #375

Merged
merged 3 commits into from
May 12, 2020
Merged

Improve error message for prepare step #375

merged 3 commits into from
May 12, 2020

Conversation

sukhil-suresh
Copy link
Contributor

  • wrap unhandled server errors returned by container registry with a more reasonable error message
  • removed redundant code from test file

Before:

[prepare] GET https://dev.registry.pivotal.io/service/token?scope=repository%3Agarbage%3Apush%2Cpull&service=harbor-registry: unsupported status code 500

After:

[prepare] Error validating write permission to dev.registry.pivotal.io/garbage. GET https://dev.registry.pivotal.io/service/token?scope=repository%3Agarbage%3Apush%2Cpull&service=harbor-registry: unsupported status code 500

Signed-off-by: Sukhil Suresh ssuresh@pivotal.io

it("wraps unhandled server errors with a reasonable error message", func() {
handler.HandleFunc("/v2/", func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(500)
})

hasAccess, err := HasWriteAccess(testKeychain{}, tagName)
require.Error(t, err)

Choose a reason for hiding this comment

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

I think there is a matcher called EqualError that allows one to also assert on the error message in the same require, but that is a minor nit.

@codecov-io
Copy link

Codecov Report

Merging #375 into master will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #375   +/-   ##
=======================================
  Coverage   67.52%   67.53%           
=======================================
  Files          81       81           
  Lines        3307     3308    +1     
=======================================
+ Hits         2233     2234    +1     
  Misses        800      800           
  Partials      274      274           
Impacted Files Coverage Δ
pkg/dockercreds/access_checker.go 80.48% <100.00%> (+0.48%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 019fd44...09939ba. Read the comment docs.

@@ -39,6 +39,7 @@ func HasWriteAccess(keychain authn.Keychain, tag string) (bool, error) {
}
}

err = errors.Errorf("Error validating write permission to %s. %s", tag, err.Error())
Copy link
Collaborator

@matthewmcnew matthewmcnew May 8, 2020

Choose a reason for hiding this comment

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

Errors are always confusing in go but, this should be an error wrap.

errors.Wrapf(err, "message %s", thing)

@matthewmcnew
Copy link
Collaborator

Right now we have two mechanisms to print errors to the user. Either the HasWriteAccess returns false or we get an unexpected error and print that out.

I wonder if HasWriteAccess should just become VerifyWriteAccess that only returns an error and print that error out if it is not nil.

@thisisnotashwin
Copy link

Right now we have two mechanisms to print errors to the user. Either the HasWriteAccess returns false or we get an unexpected error and print that out.

I wonder if HasWriteAccess should just become VerifyWriteAccess that only returns an error and print that error out if it is not nil.

im into this!!

@sukhil-suresh
Copy link
Contributor Author

sukhil-suresh commented May 8, 2020

Right now we have two mechanisms to print errors to the user. Either the HasWriteAccess returns false or we get an unexpected error and print that out.

I wonder if HasWriteAccess should just become VerifyWriteAccess that only returns an error and print that error out if it is not nil.

Aye. that makes sense. Apply the same approach to HasReadAccess check too? i.e return only an error and rename to VerifyReadAccess

@matthewmcnew
Copy link
Collaborator

VerifyReadAccess sounds like a great idea, @sukhil-suresh !

@matthewmcnew
Copy link
Collaborator

Awesome!

What does the updated output look like for 401 and 500 cases?

@sukhil-suresh
Copy link
Contributor Author

sukhil-suresh commented May 11, 2020

What does the updated output look like for 401 and 500 cases?

I captured the output for 500 in the commit message. Also below:

[prepare] Error verifying write access to "dev.registry.pivotal.io/garbage": GET https://dev.registry.pivotal.io/service/token?scope=repository%3Agarbage%3Apush%2Cpull&service=harbor-registry: unsupported status code 500

Did not keep a copy of the output for a 401.. But, the message should be prefixed identically [prepare] Error verifying write access to

Let me grab the output from an actual run and will update soon.

@sukhil-suresh
Copy link
Contributor Author

sukhil-suresh commented May 11, 2020

Checked against dockerhub with invalid creds for the 401 case:

[prepare] Error verifying write access to "index.docker.io/sukhilsuresh/spring-petclinic": Unauthorized: GET https://auth.docker.io/token?scope=repository%3Asukhilsuresh%2Fspring-petclinic%3Apush%2Cpull&service=registry.docker.io: unsupported status code 401

@sukhil-suresh
Copy link
Contributor Author

sukhil-suresh commented May 11, 2020

(Harbor specific weird case)

also the dev.registry.pivotal.io/garbage/garbage, which previously failed with the message [prepare] invalid credentials to build to dev.registry.pivotal.io/garbage/garbage

now fails with the consistent prefix and a lot more verbose error message. The additional error message was previously lost behind the false boolean, nil error return

[prepare] Error verifying write access to "dev.registry.pivotal.io/garbage/garbage": POST https://dev.registry.pivotal.io/v2/garbage/garbage/blobs/uploads/: UNAUTHORIZED: authentication required; [map[Action:pull Class: Name:garbage/garbage Type:repository] map[Action:push Class: Name:garbage/garbage Type:repository]]

@matthewmcnew
Copy link
Collaborator

I think we can merge.

I know in the past we explicitly made the decision to not show the entire verbose error message on common 401s because it is a bit confusing message with information they don't need to understand. Do you think that extra information is valuable in the 401 case?

@sukhil-suresh
Copy link
Contributor Author

I know in the past we explicitly made the decision to not show the entire verbose error message on common 401s because it is a bit confusing message with information they don't need to understand. Do you think that extra information is valuable in the 401 case?

Sorry, was not aware of the preference to limit the verbose error message!
The original error was wrapped and bubbled up with the Unauthorized message, as part of dropping the boolean return.

From what, I understand it's a case of seeing

[prepare] Error verifying write access to "index.docker.io/sukhilsuresh/spring-petclinic": Unauthorized

vs

[prepare] Error verifying write access to "index.docker.io/sukhilsuresh/spring-petclinic": Unauthorized: GET https://auth.docker.io/token?scope=repository%3Asukhilsuresh%2Fspring-petclinic%3Apush%2Cpull&service=registry.docker.io: unsupported status code 401`

To be honest, I like seeing as much detail as possible :)
Not strongly opinionated about it, so I am very open to making the error less verbose. Let me know, very minor change - drop the wrapping of error @ https://github.com/pivotal/kpack/blob/issue_357/pkg/dockercreds/access_checker.go#L33-L38

@sukhil-suresh
Copy link
Contributor Author

Made error messages less verbose for known errors

How errors look now:

  • 500
[prepare] Error verifying write access to "dev.registry.pivotal.io/garbage": GET https://dev.registry.pivotal.io/service/token?scope=repository%3Agarbage%3Apush%2Cpull&service=harbor-registry: unsupported status code 500
  • 401
[prepare] Error verifying write access to "index.docker.io/sukhilsuresh/spring-petclinic": UNAUTHORIZED
  • harbor special case (diagnosed as unauthorized)
[prepare] Error verifying write access to "dev.registry.pivotal.io/garbage/garbage": UNAUTHORIZED

- wrap unhandled server errors returnd by container registry with a more
reasonable error message
- removed redundant code from test file

Before:
```
[prepare] GET https://dev.registry.pivotal.io/service/token?scope=repository%3Agarbage%3Apush%2Cpull&service=harbor-registry: unsupported status code 500
```

After:
```
[prepare] Error validating write permission to dev.registry.pivotal.io/garbage. GET https://dev.registry.pivotal.io/service/token?scope=repository%3Agarbage%3Apush%2Cpull&service=harbor-registry: unsupported status code 500
```

Signed-off-by: Sukhil Suresh <ssuresh@pivotal.io>
- Refactor `HasWriteAccess` and `HasReadAccess` to `VerfiyWriteAccess`
and `VerifyReadAccess`. Both methods now only return an error instead of
an error and bool.
- make use of `errors.Wrapf(..)`
- make use of `assert.EqualError(..)`

Updated error message format:
```
[prepare] Error verifying write access to "dev.registry.pivotal.io/garbage": GET https://dev.registry.pivotal.io/service/token?scope=repository%3Agarbage%3Apush%2Cpull&service=harbor-registry: unsupported status code 500
```

Signed-off-by: Sukhil Suresh <ssuresh@pivotal.io>
How errors look now:

500
```
[prepare] Error verifying write access to "dev.registry.pivotal.io/garbage": GET https://dev.registry.pivotal.io/service/token?scope=repository%3Agarbage%3Apush%2Cpull&service=harbor-registry: unsupported status code 500
```

401
```
[prepare] Error verifying write access to "index.docker.io/sukhilsuresh/spring-petclinic": UNAUTHORIZED
```

harbor special case (diagnosed as unauthorized)
```
[prepare] Error verifying write access to "dev.registry.pivotal.io/garbage/garbage": UNAUTHORIZED
```

Signed-off-by: Sukhil Suresh <ssuresh@pivotal.io>
@sukhil-suresh sukhil-suresh merged commit de0c577 into master May 12, 2020
@sukhil-suresh sukhil-suresh deleted the issue_357 branch May 12, 2020 20:18
@sukhil-suresh
Copy link
Contributor Author

sukhil-suresh commented May 13, 2020

harbor special case (diagnosed as unauthorized)
[prepare] Error verifying write access to "dev.registry.pivotal.io/garbage/garbage": UNAUTHORIZED

I know it's merged, but noticed when testing (again) that the above statement is inaccurate. The harbor special case dev.registry.pivotal.io/garbage/garbage behaves differently.

[prepare] Error verifying write access to "dev.registry.pivotal.io/garbage/garbage": POST https://dev.registry.pivotal.io/v2/garbage/garbage/blobs/uploads/: UNAUTHORIZED: authentication required; [map[Action:pull Class: Name:garbage/garbage Type:repository] map[Action:push Class: Name:garbage/garbage Type:repository]]

To be fair, this is bit of an outlier case/error, but still... :(

The 401s and 500 work as expected.

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

Successfully merging this pull request may close these issues.

Prepare step's write access check fails on a 500 with harbor
4 participants