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

loose http_proxy and https_proxy check #8149

Merged
merged 1 commit into from
Aug 7, 2018
Merged

loose http_proxy and https_proxy check #8149

merged 1 commit into from
Aug 7, 2018

Conversation

wjun
Copy link
Contributor

@wjun wjun commented Jul 18, 2018

Fixes #6767

@wjun wjun requested a review from a team as a code owner July 18, 2018 23:30
zjs
zjs previously requested changes Jul 19, 2018
Copy link
Member

@zjs zjs left a comment

Choose a reason for hiding this comment

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

A few comments below. Also, could you update the commit message to be more useful? (Some advice here.)

return
}
}

if p.HTTPSProxy != nil && *p.HTTPSProxy != "" {
sproxy, err = url.Parse(*p.HTTPSProxy)
if err != nil || sproxy.Host == "" || sproxy.Scheme != "https" {
err = cli.NewExitError(fmt.Sprintf("Could not parse HTTPS proxy - expected format https://fqnd_or_ip:port: %s", *p.HTTPSProxy), 1)
if err != nil || sproxy.Host == "" || sproxy.Scheme != "https" || sproxy.Scheme != "http" {
Copy link
Member

Choose a reason for hiding this comment

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

As this validation logic is the same as above, can we extract it into a private utility method to avoid duplication?

Having the validation logic in a private method would also allow a unit test to ensure that it behaves as expected.

@@ -53,16 +53,16 @@ func (p *Proxies) ProcessProxies() (hproxy, sproxy *url.URL, err error) {
}
if p.HTTPProxy != nil && *p.HTTPProxy != "" {
hproxy, err = url.Parse(*p.HTTPProxy)
if err != nil || hproxy.Host == "" || hproxy.Scheme != "http" {
err = cli.NewExitError(fmt.Sprintf("Could not parse HTTP proxy - expected format http://fqnd_or_ip:port: %s", *p.HTTPProxy), 1)
if err != nil || hproxy.Host == "" || hproxy.Scheme != "http" || hproxy.Scheme != "https" {
Copy link
Member

Choose a reason for hiding this comment

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

hproxy.Scheme != "http" || hproxy.Scheme != "https"

I don't think this is going to achieve the intended result. (Any string will either not be "http" or not be "https", so we'll always throw an error.)

Do you mean (hproxy.Scheme != "http" && hproxy.Scheme != "https")?

@@ -418,24 +418,6 @@ Fail to create a VCH specifying an ID
# Delete Path Under Target vch/${id}


Fail to create VCH where http != https (on http key/pair) in image_fetch_proxy - registry settings
Copy link
Member

Choose a reason for hiding this comment

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

It seems like we should update these to be positive tests that you can configure "mismatched" proxies instead of removing them entirely.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. I add them into another test case where we test http(s) proxy settings.

@@ -153,6 +153,18 @@ Configure VCH https-proxy
Should Contain ${output} --http-proxy=http://proxy.vmware.com:3128
Should Not Contain ${output} --https-proxy

${output}= Run bin/vic-machine-linux configure --name=%{VCH-NAME} --target=%{TEST_URL}%{TEST_DATACENTER} --thumbprint=%{TEST_THUMBPRINT} --user=%{TEST_USERNAME} --password=%{TEST_PASSWORD} --timeout %{TEST_TIMEOUT} --http-proxy https://proxy.vmware.com:3128
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer to have the proxy pulled from the environment as this test will fail if not on the vmware internal network.
I know the test is already flawed in that regard but lets fix it up while we're making improvements.

I'm interested in moving to a situation where the test logic is independent of the infrastructure it runs on. While the bulk of that is around abstracting the topology of vSphere environments it should also include the direct manipulation of vSphere elements in tests and the infrastructure specific URIs so as this proxy server.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As far as I understand, these cases only configure proxy settings but not use them, so any correct proxy urls will be OK.

Copy link
Member

Choose a reason for hiding this comment

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

You're correct. Which suggests we should have an additional test that makes sure that we actually use the configured proxy value. That's going to be a little more involved as it would require deployment of a proxy (could be a container in a different VCH if we want to deploy as part of the test) and checking proxy logs to ensure that traffic was routed through it.

Please open a follow up issue for the functional test (as opposed to this configuration test) if that's too involved for this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

According to #8144, proxy settings are used as environment variables, so that is the very common usage of http proxies.

Copy link
Member

Choose a reason for hiding this comment

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

Your're correct. If/when we add configuration for per destination proxy configurations it will become much more involved, but for now the port layer does not use the proxy configuration so we can safely assume normal Linux proxy environment behaviour.

return
}

func (p *Proxies) validate(ref string) (proxy *url.URL, err error) {
Copy link
Member

Choose a reason for hiding this comment

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

Can we have a unit test that ensures the validation is successful for the various cases?
We do not have a test for omitting the scheme currently and I recall there was a url.Parse problem if scheme was omitted - the host portion could end up as the scheme.

I suggest testing at a minimum:

https://fully.qualified.domain.name
https://fully.qualified.domain.name:443
http://fully.qualified.domain.name
http://fully.qualified.domain.name:80
fully.qualified.domain.name
fully.qualified.domain.name:80
raw-host
raw-host:80

Copy link
Contributor Author

@wjun wjun Aug 1, 2018

Choose a reason for hiding this comment

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

Good point. I will add one. Please note our current format is http(s)://hostname, so we will get OK for the first 4 urls above, and failure for the last 4 urls.

@zjs zjs dismissed their stale review August 1, 2018 21:46

My review comments have been addressed.

@wjun wjun force-pushed the proxy branch 2 times, most recently from 4c1bc47 to 4aa0932 Compare August 2, 2018 05:39
Copy link
Member

@hickeng hickeng left a comment

Choose a reason for hiding this comment

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

Approved conditional on follow up issue for verification of proxy use and investigation of the MITM proxy test failure in https://ci-vic.vmware.com/vmware/vic/19687/7

@@ -153,6 +153,18 @@ Configure VCH https-proxy
Should Contain ${output} --http-proxy=http://proxy.vmware.com:3128
Should Not Contain ${output} --https-proxy

${output}= Run bin/vic-machine-linux configure --name=%{VCH-NAME} --target=%{TEST_URL}%{TEST_DATACENTER} --thumbprint=%{TEST_THUMBPRINT} --user=%{TEST_USERNAME} --password=%{TEST_PASSWORD} --timeout %{TEST_TIMEOUT} --http-proxy https://proxy.vmware.com:3128
Copy link
Member

Choose a reason for hiding this comment

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

You're correct. Which suggests we should have an additional test that makes sure that we actually use the configured proxy value. That's going to be a little more involved as it would require deployment of a proxy (could be a container in a different VCH if we want to deploy as part of the test) and checking proxy logs to ensure that traffic was routed through it.

Please open a follow up issue for the functional test (as opposed to this configuration test) if that's too involved for this PR.

)

func TestProcessProxies(t *testing.T) {
urls := [...]string{
Copy link
Member

@zjs zjs Aug 2, 2018

Choose a reason for hiding this comment

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

Can we put the good urls and bad urls into separate slices so that we can test combinations where HTTPProxy != HTTPSProxy? Something like this would also allow us to check combinations more combinations, including combinations of valid & invalid proxies.

This also makes it easier to add new URLs without needing to update the logic later in the test.

I think it also makes sense to replace the example domains suggested by George with domain names that are reserved for such use, to avoid using potentially valid domains that we do not own. (For IP addresses, I refer to subnets reserved in RFC 3849 and RFC 5737.)

Lastly, I think it's helpful to use the optional msg arguments to ensure that a helpful message is printed if the test fails. (Debugging failures in CI can be annoying if all that's logged is something like true != false.)

Example of what I mean:

	gurls := [...]string{
		"https://fully.qualified.example.com",
		"https://fully.qualified.example.com:443",
		"http://fully.qualified.example.com",
		"http://fully.qualified.example.com:80", 
		"http://203.0.113.123", 
		"http://[2001:DB8:0123::]", 
	}

	burls := [...]string{
		"example.com",
		"example.com:80",
		"localhost",
		"localhost:80",
		"ftp://example.com",
		"httpd://example.com",
	}

	for _, ghttp := range gproxies {
		for _, ghttps := range gproxies {
			gproxy := Proxies{HTTPProxy: &ghttp, HTTPSProxy: &ghttps}

			_, _, err := gproxy.ProcessProxies()
			assert.NoError(t, err, "Expected %s and %s to be accepted", ghttp, ghttps)
			assert.True(t, gproxy.IsSet, "Expected proxy to be marked as set")
		}
 	} 

	for _, ghttp := range gproxies {
		for _, bhttps := range gproxies {
			bproxy := Proxies{HTTPProxy: &ghttp, HTTPSProxy: &bhttps}

			_, _, err := bproxy.ProcessProxies()
			assert.Error(t, err, "Expected %s to be rejected", bhttps)
		}
 	} 

	for _, bhttp := range gproxies {
		for _, ghttps := range gproxies {
			bproxy := Proxies{HTTPProxy: &bhttp, HTTPSProxy: &ghttps}

			_, _, err := bproxy.ProcessProxies()
			assert.Error(t, err, "Expected %s to be rejected", bhttp)
		}
 	} 

	for _, bhttp := range gproxies {
		for _, bhttps := range gproxies {
			bproxy := Proxies{HTTPProxy: &bhttp, HTTPSProxy: &bhttps}

			_, _, err := bproxy.ProcessProxies()
			assert.Error(t, err, "Expected %s and %s to be rejected", bhttp, bhttps)
		}
 	} 

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestions. Initially, I thought most users will set http/https proxy to the same proxy server, and this refactoring definitely covers all cases and easier to extend.

@@ -153,6 +153,18 @@ Configure VCH https-proxy
Should Contain ${output} --http-proxy=http://proxy.vmware.com:3128
Should Not Contain ${output} --https-proxy

${output}= Run bin/vic-machine-linux configure --name=%{VCH-NAME} --target=%{TEST_URL}%{TEST_DATACENTER} --thumbprint=%{TEST_THUMBPRINT} --user=%{TEST_USERNAME} --password=%{TEST_PASSWORD} --timeout %{TEST_TIMEOUT} --http-proxy https://proxy.vmware.com:3128
Copy link
Member

Choose a reason for hiding this comment

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

Your're correct. If/when we add configuration for per destination proxy configurations it will become much more involved, but for now the port layer does not use the proxy configuration so we can safely assume normal Linux proxy environment behaviour.

@wjun wjun merged commit 19788ca into vmware:master Aug 7, 2018
zjs pushed a commit to zjs/vic that referenced this pull request Aug 7, 2018
zjs added a commit that referenced this pull request Aug 10, 2018
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.

4 participants