diff --git a/cmd/githubrunnerscalesetlistener/main.go b/cmd/githubrunnerscalesetlistener/main.go index ed9f145f..3813617a 100644 --- a/cmd/githubrunnerscalesetlistener/main.go +++ b/cmd/githubrunnerscalesetlistener/main.go @@ -19,6 +19,8 @@ package main import ( "context" "fmt" + "net/http" + "net/url" "os" "os/signal" "syscall" @@ -28,6 +30,7 @@ import ( "github.com/actions/actions-runner-controller/logging" "github.com/go-logr/logr" "github.com/kelseyhightower/envconfig" + "golang.org/x/net/http/httpproxy" ) type RunnerScaleSetListenerConfig struct { @@ -84,8 +87,8 @@ func run(rc RunnerScaleSetListenerConfig, logger logr.Logger) error { } } - actionsServiceClient, err := actions.NewClient( - rc.ConfigureUrl, + actionsServiceClient, err := newActionsClientFromConfig( + rc, creds, actions.WithUserAgent(fmt.Sprintf("actions-runner-controller/%s", build.Version)), actions.WithLogger(logger), @@ -155,3 +158,12 @@ func validateConfig(config *RunnerScaleSetListenerConfig) error { return nil } + +func newActionsClientFromConfig(config RunnerScaleSetListenerConfig, creds *actions.ActionsAuth, options ...actions.ClientOption) (*actions.Client, error) { + proxyFunc := httpproxy.FromEnvironment().ProxyFunc() + options = append(options, actions.WithProxy(func(req *http.Request) (*url.URL, error) { + return proxyFunc(req.URL) + })) + + return actions.NewClient(config.ConfigureUrl, creds, options...) +} diff --git a/cmd/githubrunnerscalesetlistener/main_test.go b/cmd/githubrunnerscalesetlistener/main_test.go index bd2d7187..619bfeb6 100644 --- a/cmd/githubrunnerscalesetlistener/main_test.go +++ b/cmd/githubrunnerscalesetlistener/main_test.go @@ -2,9 +2,15 @@ package main import ( "fmt" + "net/http" + "net/http/httptest" + "os" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/actions/actions-runner-controller/github/actions" ) func TestConfigValidationMinMax(t *testing.T) { @@ -90,3 +96,106 @@ func TestConfigValidationConfigUrl(t *testing.T) { assert.ErrorContains(t, err, "GitHubConfigUrl is not provided", "Expected error about missing ConfigureUrl") } + +func TestProxySettings(t *testing.T) { + t.Run("http", func(t *testing.T) { + wentThroughProxy := false + + proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + wentThroughProxy = true + })) + t.Cleanup(func() { + proxy.Close() + }) + + prevProxy := os.Getenv("http_proxy") + os.Setenv("http_proxy", proxy.URL) + defer os.Setenv("http_proxy", prevProxy) + + config := RunnerScaleSetListenerConfig{ + ConfigureUrl: "https://github.com/org/repo", + } + creds := &actions.ActionsAuth{ + Token: "token", + } + + client, err := newActionsClientFromConfig(config, creds) + require.NoError(t, err) + + req, err := http.NewRequest(http.MethodGet, "http://example.com", nil) + require.NoError(t, err) + _, err = client.Do(req) + require.NoError(t, err) + + assert.True(t, wentThroughProxy) + }) + + t.Run("https", func(t *testing.T) { + wentThroughProxy := false + + proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + wentThroughProxy = true + })) + t.Cleanup(func() { + proxy.Close() + }) + + prevProxy := os.Getenv("https_proxy") + os.Setenv("https_proxy", proxy.URL) + defer os.Setenv("https_proxy", prevProxy) + + config := RunnerScaleSetListenerConfig{ + ConfigureUrl: "https://github.com/org/repo", + } + creds := &actions.ActionsAuth{ + Token: "token", + } + + client, err := newActionsClientFromConfig(config, creds, actions.WithRetryMax(0)) + require.NoError(t, err) + + req, err := http.NewRequest(http.MethodGet, "https://example.com", nil) + require.NoError(t, err) + + _, err = client.Do(req) + // proxy doesn't support https + assert.Error(t, err) + assert.True(t, wentThroughProxy) + }) + + t.Run("no_proxy", func(t *testing.T) { + wentThroughProxy := false + + proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + wentThroughProxy = true + })) + t.Cleanup(func() { + proxy.Close() + }) + + prevProxy := os.Getenv("http_proxy") + os.Setenv("http_proxy", proxy.URL) + defer os.Setenv("http_proxy", prevProxy) + + prevNoProxy := os.Getenv("no_proxy") + os.Setenv("no_proxy", "example.com") + defer os.Setenv("no_proxy", prevNoProxy) + + config := RunnerScaleSetListenerConfig{ + ConfigureUrl: "https://github.com/org/repo", + } + creds := &actions.ActionsAuth{ + Token: "token", + } + + client, err := newActionsClientFromConfig(config, creds) + require.NoError(t, err) + + req, err := http.NewRequest(http.MethodGet, "http://example.com", nil) + require.NoError(t, err) + + _, err = client.Do(req) + require.NoError(t, err) + assert.False(t, wentThroughProxy) + }) +}