Apply proxy settings from environment in listener (#2366)

Co-authored-by: Tingluo Huang <tingluohuang@github.com>
This commit is contained in:
Francesco Renzi 2023-03-06 19:21:22 +00:00 committed by GitHub
parent 91fddca3f7
commit e289fe43d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 123 additions and 2 deletions

View File

@ -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...)
}

View File

@ -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)
})
}