Commit b6739303 authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #1866 from mslipper/feat/eng-1728-env-vars

go/proxyd: Add support for env vars in the config
parents 6910504e 73484138
---
'@eth-optimism/proxyd': minor
---
Adds ability to specify env vars in config
package proxyd package proxyd
import (
"fmt"
"os"
"strings"
)
type ServerConfig struct { type ServerConfig struct {
RPCHost string `toml:"rpc_host"` RPCHost string `toml:"rpc_host"`
RPCPort int `toml:"rpc_port"` RPCPort int `toml:"rpc_port"`
...@@ -26,11 +32,11 @@ type BackendOptions struct { ...@@ -26,11 +32,11 @@ type BackendOptions struct {
} }
type BackendConfig struct { type BackendConfig struct {
Username string `toml:"username"` Username string `toml:"username"`
Password string `toml:"password"` Password string `toml:"password"`
RPCURL string `toml:"rpc_url"` RPCURL string `toml:"rpc_url"`
WSURL string `toml:"ws_url"` WSURL string `toml:"ws_url"`
MaxRPS int `toml:"max_rps"` MaxRPS int `toml:"max_rps"`
MaxWSConns int `toml:"max_ws_conns"` MaxWSConns int `toml:"max_ws_conns"`
CAFile string `toml:"ca_file"` CAFile string `toml:"ca_file"`
ClientCertFile string `toml:"client_cert_file"` ClientCertFile string `toml:"client_cert_file"`
...@@ -59,3 +65,19 @@ type Config struct { ...@@ -59,3 +65,19 @@ type Config struct {
RPCMethodMappings map[string]string `toml:"rpc_method_mappings"` RPCMethodMappings map[string]string `toml:"rpc_method_mappings"`
WSMethodWhitelist []string `toml:"ws_method_whitelist"` WSMethodWhitelist []string `toml:"ws_method_whitelist"`
} }
func ReadFromEnvOrConfig(value string) (string, error) {
if strings.HasPrefix(value, "$") {
envValue := os.Getenv(strings.TrimPrefix(value, "$"))
if envValue == "" {
return "", fmt.Errorf("config env var %s not found", value)
}
return envValue, nil
}
if strings.HasPrefix(value, "\\") {
return strings.TrimPrefix(value, "\\"), nil
}
return value, nil
}
...@@ -44,11 +44,15 @@ out_of_service_seconds = 600 ...@@ -44,11 +44,15 @@ out_of_service_seconds = 600
[backends] [backends]
# A map of backends by name. # A map of backends by name.
[backends.infura] [backends.infura]
# The URL to contact the backend at. # The URL to contact the backend at. Will be read from the environment
# if an environment variable prefixed with $ is provided.
rpc_url = "" rpc_url = ""
# The WS URL to contact the backend at. # The WS URL to contact the backend at. Will be read from the environment
# if an environment variable prefixed with $ is provided.
ws_url = "" ws_url = ""
username = "" username = ""
# An HTTP Basic password to authenticate with the backend. Will be read from
# the environment if an environment variable prefixed with $ is provided.
password = "" password = ""
max_rps = 3 max_rps = 3
max_ws_conns = 1 max_ws_conns = 1
...@@ -60,7 +64,6 @@ client_cert_file = "" ...@@ -60,7 +64,6 @@ client_cert_file = ""
client_key_file = "" client_key_file = ""
[backends.alchemy] [backends.alchemy]
# The URL to contact the backend at.
rpc_url = "" rpc_url = ""
ws_url = "" ws_url = ""
username = "" username = ""
...@@ -79,7 +82,10 @@ backends = ["alchemy"] ...@@ -79,7 +82,10 @@ backends = ["alchemy"]
# proxyd will only accept authenticated requests. # proxyd will only accept authenticated requests.
[authentication] [authentication]
# Mapping of auth key to alias. The alias is used to provide a human- # Mapping of auth key to alias. The alias is used to provide a human-
# readable name for the auth key in monitoring. # readable name for the auth key in monitoring. The auth key will be
# read from the environment if an environment variable prefixed with $
# is provided. Note that you will need to quote the environment variable
# in order for it to be value TOML, e.g. "$FOO_AUTH_KEY" = "foo_alias".
secret = "test" secret = "test"
# Mapping of methods to backend groups. # Mapping of methods to backend groups.
......
...@@ -47,10 +47,18 @@ func Start(config *Config) error { ...@@ -47,10 +47,18 @@ func Start(config *Config) error {
for name, cfg := range config.Backends { for name, cfg := range config.Backends {
opts := make([]BackendOpt, 0) opts := make([]BackendOpt, 0)
if cfg.RPCURL == "" { rpcURL, err := ReadFromEnvOrConfig(cfg.RPCURL)
if err != nil {
return err
}
wsURL, err := ReadFromEnvOrConfig(cfg.WSURL)
if err != nil {
return err
}
if rpcURL == "" {
return fmt.Errorf("must define an RPC URL for backend %s", name) return fmt.Errorf("must define an RPC URL for backend %s", name)
} }
if cfg.WSURL == "" { if wsURL == "" {
return fmt.Errorf("must define a WS URL for backend %s", name) return fmt.Errorf("must define a WS URL for backend %s", name)
} }
...@@ -74,7 +82,11 @@ func Start(config *Config) error { ...@@ -74,7 +82,11 @@ func Start(config *Config) error {
opts = append(opts, WithMaxWSConns(cfg.MaxWSConns)) opts = append(opts, WithMaxWSConns(cfg.MaxWSConns))
} }
if cfg.Password != "" { if cfg.Password != "" {
opts = append(opts, WithBasicAuth(cfg.Username, cfg.Password)) passwordVal, err := ReadFromEnvOrConfig(cfg.Password)
if err != nil {
return err
}
opts = append(opts, WithBasicAuth(cfg.Username, passwordVal))
} }
tlsConfig, err := configureBackendTLS(cfg) tlsConfig, err := configureBackendTLS(cfg)
if err != nil { if err != nil {
...@@ -84,10 +96,10 @@ func Start(config *Config) error { ...@@ -84,10 +96,10 @@ func Start(config *Config) error {
log.Info("using custom TLS config for backend", "name", name) log.Info("using custom TLS config for backend", "name", name)
opts = append(opts, WithTLSConfig(tlsConfig)) opts = append(opts, WithTLSConfig(tlsConfig))
} }
back := NewBackend(name, cfg.RPCURL, cfg.WSURL, lim, opts...) back := NewBackend(name, rpcURL, wsURL, lim, opts...)
backendNames = append(backendNames, name) backendNames = append(backendNames, name)
backendsByName[name] = back backendsByName[name] = back
log.Info("configured backend", "name", name, "rpc_url", cfg.RPCURL, "ws_url", cfg.WSURL) log.Info("configured backend", "name", name, "rpc_url", rpcURL, "ws_url", wsURL)
} }
backendGroups := make(map[string]*BackendGroup) backendGroups := make(map[string]*BackendGroup)
...@@ -124,13 +136,26 @@ func Start(config *Config) error { ...@@ -124,13 +136,26 @@ func Start(config *Config) error {
} }
} }
var resolvedAuth map[string]string
if config.Authentication != nil {
resolvedAuth = make(map[string]string)
for secret, alias := range config.Authentication {
resolvedSecret, err := ReadFromEnvOrConfig(secret)
if err != nil {
return err
}
resolvedAuth[resolvedSecret] = alias
}
}
srv := NewServer( srv := NewServer(
backendGroups, backendGroups,
wsBackendGroup, wsBackendGroup,
NewStringSetFromStrings(config.WSMethodWhitelist), NewStringSetFromStrings(config.WSMethodWhitelist),
config.RPCMethodMappings, config.RPCMethodMappings,
config.Server.MaxBodySizeBytes, config.Server.MaxBodySizeBytes,
config.Authentication, resolvedAuth,
) )
if config.Metrics.Enabled { if config.Metrics.Enabled {
......
...@@ -20,7 +20,7 @@ func CreateTLSClient(ca string) (*tls.Config, error) { ...@@ -20,7 +20,7 @@ func CreateTLSClient(ca string) (*tls.Config, error) {
} }
return &tls.Config{ return &tls.Config{
RootCAs: roots, RootCAs: roots,
}, nil }, nil
} }
...@@ -30,4 +30,4 @@ func ParseKeyPair(crt, key string) (tls.Certificate, error) { ...@@ -30,4 +30,4 @@ func ParseKeyPair(crt, key string) (tls.Certificate, error) {
return tls.Certificate{}, wrapErr(err, "error loading x509 key pair") return tls.Certificate{}, wrapErr(err, "error loading x509 key pair")
} }
return cert, nil return cert, nil
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment