-
Notifications
You must be signed in to change notification settings - Fork 154
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
resolve proxy to inject using http package #6675
Conversation
This pull request does not have a backport label. Could you fix it @intxgo? 🙏
|
Looking at endpoint's Proxy.cpp I see the following suggesting this needs a change in endpoint as well. Is that correct? // This mimic GO implementation, though we don't support the NO_PROXY list of IP's which should
// be accessed without proxy
//
// https://pkg.go.dev/golang.org/x/net/http/httpproxy This is a separate thing. Indeed if an environment proxy is set on Endpoint, it'll skip the NO_PROXY. However, it doesn't matter for this fix since when Agent injects it's environment proxy into Endpoint config, then it takes priority at Endpoint side over environment proxy. Much like |
proxyURL = os.Getenv("HTTPS_PROXY") | ||
if proxyURL == "" { | ||
proxyURL = os.Getenv("HTTP_PROXY") | ||
proxyURL, err := http.ProxyFromEnvironment(request) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 didn't know this existed!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this function in its current form is the problem in the tests. If you look at the implementation it is just calling https://cs.opensource.google/go/go/+/master:src/net/http/transport.go?q=FromEnvironment&ss=go%2Fgo
func ProxyFromEnvironment(req *Request) (*url.URL, error) {
return envProxyFunc()(req.URL)
}
// envProxyFunc returns a function that reads the
// environment variable to determine the proxy address.
func envProxyFunc() func(*url.URL) (*url.URL, error) {
envProxyOnce.Do(func() {
envProxyFuncValue = httpproxy.FromEnvironment().ProxyFunc()
})
return envProxyFuncValue
}
If you directly get a reference to httpproxy.FromEnvironment().ProxyFunc() yourself I think the problem goes away as you skip the do.Once
. The following fixes the tests. You could maybe be smarter and not re-read from the environment on every configuration change if you wanted to, I'm not sure that efficiency matters here.
diff --git a/internal/pkg/agent/application/inject_proxy_component_modifier.go b/internal/pkg/agent/application/inject_proxy_component_modifier.go
index d8eb9f1e98..2f68e7452c 100644
--- a/internal/pkg/agent/application/inject_proxy_component_modifier.go
+++ b/internal/pkg/agent/application/inject_proxy_component_modifier.go
@@ -10,6 +10,7 @@ import (
"github.com/elastic/elastic-agent-client/v7/pkg/client"
"github.com/elastic/elastic-agent/internal/pkg/agent/application/coordinator"
"github.com/elastic/elastic-agent/pkg/component"
+ "golang.org/x/net/http/httpproxy"
)
// InjectProxyEndpointModifier injects a proxy_url value into endpoint's output config if one is not set.
@@ -84,7 +85,7 @@ func injectProxyURL(m map[string]interface{}, hosts []string) {
if err != nil {
continue
}
- proxyURL, err := http.ProxyFromEnvironment(request)
+ proxyURL, err := httpproxy.FromEnvironment().ProxyFunc()(request.URL)
if err != nil {
continue
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. This will theoretically departure a tiny bit from the desired goal to have Endpoint behaving exactly as Agent, because Agent will read the environment only once for it's http operations. However since the environment on a process can be only modified from within the process, by debugger, etc, but not just by modifying system configuration LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated 04d509d
I probably found the culprit of the unit tests failure. The Indeed, even locally when I run all tests I get the same failure. Experimenting I've found that environment proxy set in the shell before test execution is not overridden by
Could it be that these env variables are set on the testing nodes but with empty strings? @cmacknz @michel-laterman do you know if we could set those env variables on the test nodes like above? If yes, how to do this? |
The
Edit I can reproduce locally with: |
OK so the problem isn't It includes a do.Once to setup the proxy func and I think this only reads the env vars one time. https://cs.opensource.google/go/go/+/refs/tags/go1.23.5:src/net/http/transport.go;l=907-914 This has something to do with at which point in the tests the variables are read I think.
|
Thanks for checking for the root cause. Do you have a suggestion then how to handle it in tests? Obviously this works correctly in the product as Agent process will just see environment it was started with. Failure to write a test doesn't justify keeping a bug, but I'm out of ideas. (I don't think re-implementing this function is the right approach). |
894f882
to
04d509d
Compare
Pinging @elastic/elastic-agent-control-plane (Team:Elastic-Agent-Control-Plane) |
|
* resolve proxy to inject using http package * unit tests * golint * golint * changelog fragment * changelog fragment * move environment manipulation, trying to fix test run in CI * fix unit test, localhost never goes through environment proxy * use internal function to be able to unit test the behavior * make lint happy * fix build * update NOTICE (cherry picked from commit be179d8) # Conflicts: # NOTICE.txt # go.mod
* resolve proxy to inject using http package * unit tests * golint * golint * changelog fragment * changelog fragment * move environment manipulation, trying to fix test run in CI * fix unit test, localhost never goes through environment proxy * use internal function to be able to unit test the behavior * make lint happy * fix build * update NOTICE (cherry picked from commit be179d8)
* resolve proxy to inject using http package * unit tests * golint * golint * changelog fragment * changelog fragment * move environment manipulation, trying to fix test run in CI * fix unit test, localhost never goes through environment proxy * use internal function to be able to unit test the behavior * make lint happy * fix build * update NOTICE (cherry picked from commit be179d8)
* resolve proxy to inject using http package * unit tests * golint * golint * changelog fragment * changelog fragment * move environment manipulation, trying to fix test run in CI * fix unit test, localhost never goes through environment proxy * use internal function to be able to unit test the behavior * make lint happy * fix build * update NOTICE (cherry picked from commit be179d8)
* resolve proxy to inject using http package * unit tests * golint * golint * changelog fragment * changelog fragment * move environment manipulation, trying to fix test run in CI * fix unit test, localhost never goes through environment proxy * use internal function to be able to unit test the behavior * make lint happy * fix build * update NOTICE (cherry picked from commit be179d8)
* resolve proxy to inject using http package * unit tests * golint * golint * changelog fragment * changelog fragment * move environment manipulation, trying to fix test run in CI * fix unit test, localhost never goes through environment proxy * use internal function to be able to unit test the behavior * make lint happy * fix build * update NOTICE (cherry picked from commit be179d8) Co-authored-by: Leszek Kubik <[email protected]>
* resolve proxy to inject using http package * unit tests * golint * golint * changelog fragment * changelog fragment * move environment manipulation, trying to fix test run in CI * fix unit test, localhost never goes through environment proxy * use internal function to be able to unit test the behavior * make lint happy * fix build * update NOTICE (cherry picked from commit be179d8) Co-authored-by: Leszek Kubik <[email protected]>
What does this PR do?
Agent is injecting proxy env variables into components configs if no proxy is already specified by the config. Unfortunately with this approach the NO_PROXY variable is lost, so the target URL has to be evaluated against the environment proxy to determine if the proxy should be used. Go http provides such functionality.
Why is it important?
The environment proxy may be defined with exclusion for Fleet and Output addresses.
Checklist
./changelog/fragments
using the changelog toolRelated issues
HTTP_PROXY/HTTPS_PROXY/NO_PROXY
to components. #2602