Apply proxy settings from environment in listener (#2366)
Co-authored-by: Tingluo Huang <tingluohuang@github.com>
This commit is contained in:
		
							parent
							
								
									91fddca3f7
								
							
						
					
					
						commit
						e289fe43d4
					
				|  | @ -19,6 +19,8 @@ package main | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"net/http" | ||||||
|  | 	"net/url" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/signal" | 	"os/signal" | ||||||
| 	"syscall" | 	"syscall" | ||||||
|  | @ -28,6 +30,7 @@ import ( | ||||||
| 	"github.com/actions/actions-runner-controller/logging" | 	"github.com/actions/actions-runner-controller/logging" | ||||||
| 	"github.com/go-logr/logr" | 	"github.com/go-logr/logr" | ||||||
| 	"github.com/kelseyhightower/envconfig" | 	"github.com/kelseyhightower/envconfig" | ||||||
|  | 	"golang.org/x/net/http/httpproxy" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type RunnerScaleSetListenerConfig struct { | type RunnerScaleSetListenerConfig struct { | ||||||
|  | @ -84,8 +87,8 @@ func run(rc RunnerScaleSetListenerConfig, logger logr.Logger) error { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	actionsServiceClient, err := actions.NewClient( | 	actionsServiceClient, err := newActionsClientFromConfig( | ||||||
| 		rc.ConfigureUrl, | 		rc, | ||||||
| 		creds, | 		creds, | ||||||
| 		actions.WithUserAgent(fmt.Sprintf("actions-runner-controller/%s", build.Version)), | 		actions.WithUserAgent(fmt.Sprintf("actions-runner-controller/%s", build.Version)), | ||||||
| 		actions.WithLogger(logger), | 		actions.WithLogger(logger), | ||||||
|  | @ -155,3 +158,12 @@ func validateConfig(config *RunnerScaleSetListenerConfig) error { | ||||||
| 
 | 
 | ||||||
| 	return nil | 	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...) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -2,9 +2,15 @@ package main | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"net/http" | ||||||
|  | 	"net/http/httptest" | ||||||
|  | 	"os" | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
|  | 	"github.com/stretchr/testify/require" | ||||||
|  | 
 | ||||||
|  | 	"github.com/actions/actions-runner-controller/github/actions" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestConfigValidationMinMax(t *testing.T) { | 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") | 	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) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue