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

Make allowInsecureRegistries follow Docker semantics #733

Merged
merged 16 commits into from
Aug 1, 2018

Conversation

chanseokoh
Copy link
Member

Fixes #643.

Before:
call(URL) embedded the logic for handling allowInsecureRegistries.

Now:
The logic is broken out of call(URL) into callWithInsecureRegistryHandling(). call(URL) always contacts the endpoint and is irrelevant of allowInsecureRegistries. callWithInsecureRegistryHandling() is the one that handles allowInsecureRegistries.

@@ -125,7 +130,37 @@
*/
@Nullable
T call() throws IOException, RegistryException {
return call(initialRequestUrl);
return callWithInsecureRegistryHandling(initialRequestUrl);
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, I feel like the checking should be done here for whether or not to handle insecure registries based on the flag so that it launches two codepaths - one for calling without allowing insecure registries, and one for calling with allowing insecure registries - rather than have that logic be encapsulated in callWithInsecureRegistryHandling. From the function call here, it seems like insecure registry handling is the default.

Copy link
Member Author

@chanseokoh chanseokoh Jul 27, 2018

Choose a reason for hiding this comment

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

it launches two codepaths

It's not exactly like there will be two codepaths based on allowInsecureRegistries. They cross-over, for example, you can first contact an HTTP server (failover-to-HTTP occurred) which redirects you to a secure HTTPS server (or vice versa). With callWithInsecureRegistryHandling(), you don't have to think about those things anymore. You just pass a URL to callWithInsecureRegistryHandling() recursively and it will handle things correctly.

From the function call here, it seems like insecure registry handling is the default.

You are saying the naming callWithInsecureRegistryHandling is giving you the impression that it will attempt insecure communication, right? I'll think about a better name, but if you have some suggestions, let me know.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah yes, I'm thinking about this more in the lines of having allowInsecureRegistries be checked in one location to launch separate codepaths, one for secure and one for insecure. The one for insecure will be essentially the one for secure, except with additional functionality for handling HTTPS connect/TLS verification errors (codepaths with cross-over, but a different entrypoint). So, rather than checking allowInsecureRegistries in multiple places in callWithInsecureRegistryHandling, a single check would determine if the insecure handling code entrypoint would be launched vs the secure handling code entrypoint. I think I need to think more about this too.

Copy link
Member Author

@chanseokoh chanseokoh Jul 27, 2018

Choose a reason for hiding this comment

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

So, rather than checking allowInsecureRegistries in multiple places in callWithInsecureRegistryHandling, a single check would determine if the insecure handling code entrypoint would be launched vs the secure handling code entrypoint.

I think I got what you mean. That makes sense too. I'll try your idea and push up changes, and then we can evaluate which one will look better.

Copy link
Member Author

Choose a reason for hiding this comment

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

Here's the attempt with your idea, if I understood it correctly: 6df4b42

I'm fine with either ways.

return call(url, insecureConnectionFactory);

} catch (GeneralSecurityException ex) {
throw new RegistryException("cannot turn off TLS peer verification", ex);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: newline after

throw new RegistryException("cannot turn off TLS peer verification", ex);

} catch (SSLPeerUnverifiedException | HttpHostConnectException ex) {
// Try HTTP as a last resort.
Copy link
Contributor

Choose a reason for hiding this comment

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

For example, here, I think this would allow HTTP fallback even if allowInsecureRegistries was false.

Copy link
Member Author

Choose a reason for hiding this comment

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

That can never happen. If allowInsecureRegistries is false and the server is not a verifiable HTTPS, it will throw an exception.

        // Cannot verify the server (e.g., self-signed certificate or plain HTTP).
        if (!allowInsecureRegistries) {
          throw new InsecureRegistryException(url);
        }

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah right, I need to read this more carefully.

Copy link
Contributor

@coollog coollog 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 this looks better, but going to request for more opinions @GoogleContainerTools/java-tools

} catch (SSLPeerUnverifiedException exception) {
try {
if (insecureConnectionFactory == null) {
insecureConnectionFactory = Connection.getInsecureConnectionFactory();
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, it seems that insecureConnectionFactory doesn't need to be an instance variable.

Copy link
Member Author

Choose a reason for hiding this comment

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

In fact, connectionFactory doesn't have to be so either, but it was there from the beginning, and I believe it is for mocking Connection. insecureConnectionFactory is there for the same reason.

But I guess you will wonder why the code has this null check.

        Connection.getConnectionFactory(),
        null /* might never be used, so create lazily to delay throwing potential GeneralSecurityException */);

So this is to avoid the potential GeneralSecurityException when creating the insecureConnectionFactory. For example, if the user never sets allowInsecureRegistries or the server was secure even if it was set, we can proceed without an error in the situation where GeneralSecurityException will otherwise be thrown if blindly created at the beginning.

@chanseokoh
Copy link
Member Author

Here's the attempt with your idea, if I understood it correctly: 6df4b42
I'm fine with either ways.

I think this looks better, but going to request for more opinions @GoogleContainerTools/java-tools

Personally, I slightly prefer the previous approach for the following reasons:

  1. After 6df4b42, you add one more method (possiblyInsecureCall) with similar names:
    • call()
    • callWithAllowInsecureRegistryHandling()
    • possiblyInsecureCall()
    • call(URL)
  2. Although callWithAllowInsecureRegistryHandling() is now basically for determining the two different codepaths based on allowInsecureRegistries, the behavior of possiblyInsecureCall() is identical to that of callWithAllowInsecureRegistryHandling() if the endpoint is secure HTTPS, whether allowInsecureRegistries is true or not.

However, I usually and casually follow the feedback from reviewers, and the new code seems fine to me, so I'll go for the new code. It has its own merits too.

@coollog
Copy link
Contributor

coollog commented Jul 28, 2018

I think drawing out a state diagram might help with this - I'll sketch up something when I get back to somewhere with paper.

coollog
coollog previously approved these changes Aug 1, 2018
Copy link
Contributor

@coollog coollog left a comment

Choose a reason for hiding this comment

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

Feel free to dismiss this approval if making more changes.

@chanseokoh chanseokoh dismissed coollog’s stale review August 1, 2018 16:29

Made non-negligible changes

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.

2 participants