actions-runner-controller/proxyconfig/proxyconfig.go

134 lines
2.7 KiB
Go

package proxyconfig
import (
"fmt"
"net/url"
"os"
"strings"
"golang.org/x/net/http/httpproxy"
)
type ProxyConfig struct {
HTTP *ProxyServerConfig `json:"http,omitempty"`
HTTPS *ProxyServerConfig `json:"https,omitempty"`
NoProxy []string `json:"no_proxy,omitempty"`
}
func (pc *ProxyConfig) Validate() error {
if pc == nil {
return nil
}
if pc.HTTP != nil {
_, err := url.ParseRequestURI(pc.HTTP.URL)
if err != nil {
return fmt.Errorf("proxy http set with invalid url: %v", err)
}
}
if pc.HTTPS != nil {
_, err := url.ParseRequestURI(pc.HTTPS.URL)
if err != nil {
return fmt.Errorf("proxy https set with invalid url: %v", err)
}
}
for _, u := range pc.NoProxy {
if _, err := url.ParseRequestURI(u); err != nil {
return fmt.Errorf("proxy no_proxy set with invalid url: %v", err)
}
}
return nil
}
func (c *ProxyConfig) ProxyConfig() (*httpproxy.Config, error) {
if c == nil {
return nil, nil
}
config := &httpproxy.Config{
NoProxy: strings.Join(c.NoProxy, ","),
}
if c.HTTP != nil {
u, err := c.HTTP.proxyURL()
if err != nil {
return nil, fmt.Errorf("failed to create proxy http url: %w", err)
}
config.HTTPProxy = u.String()
}
if c.HTTPS != nil {
u, err := c.HTTPS.proxyURL()
if err != nil {
return nil, fmt.Errorf("failed to create proxy https url: %w", err)
}
config.HTTPSProxy = u.String()
}
return config, nil
}
type ProxyServerConfig struct {
URL string `json:"url"`
Username string `json:"username"`
Password string `json:"password"`
}
func (c *ProxyServerConfig) proxyURL() (*url.URL, error) {
u, err := url.Parse(c.URL)
if err != nil {
return nil, fmt.Errorf("failed to parse proxy url %q: %w", c.URL, err)
}
u.User = url.UserPassword(
c.Username,
c.Password,
)
return u, nil
}
func ReadFromEnv(prefix string) (*ProxyConfig, error) {
url := os.Getenv(prefix + "HTTP_URL")
username := os.Getenv(prefix + "HTTP_USERNAME")
password := os.Getenv(prefix + "HTTP_PASSWORD")
var http *ProxyServerConfig
if url != "" || username != "" || password != "" {
http = &ProxyServerConfig{
URL: url,
Username: username,
Password: password,
}
}
url = os.Getenv(prefix + "HTTPS_URL")
username = os.Getenv(prefix + "HTTPS_USERNAME")
password = os.Getenv(prefix + "HTTPS_PASSWORD")
var https *ProxyServerConfig
if url != "" || username != "" || password != "" {
https = &ProxyServerConfig{
URL: url,
Username: username,
Password: password,
}
}
noProxyRaw := os.Getenv(prefix + "NO_PROXY")
if http == nil && https == nil && noProxyRaw == "" {
return nil, nil
}
var noProxy []string
if noProxyRaw != "" {
noProxy = strings.Split(noProxyRaw, ",")
}
return &ProxyConfig{
HTTP: http,
HTTPS: https,
NoProxy: noProxy,
}, nil
}