2024-03-26 17:28:38 +01:00
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"forge.cadoles.com/cadoles/bouncer/internal/store"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
|
|
)
|
|
|
|
|
|
|
|
type BootstrapConfig struct {
|
2024-04-05 10:30:34 +02:00
|
|
|
Proxies map[store.ProxyName]BootstrapProxyConfig `yaml:"proxies"`
|
|
|
|
Dir InterpolatedString `yaml:"dir"`
|
|
|
|
LockTimeout InterpolatedDuration `yaml:"lockTimeout"`
|
|
|
|
MaxConnectionRetries InterpolatedInt `yaml:"maxRetries"`
|
2024-03-26 17:28:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *BootstrapConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|
|
|
src := struct {
|
|
|
|
Proxies map[store.ProxyName]BootstrapProxyConfig `yaml:"proxies"`
|
|
|
|
Dir InterpolatedString `yaml:"dir"`
|
|
|
|
}{
|
|
|
|
Proxies: make(map[store.ProxyName]BootstrapProxyConfig),
|
|
|
|
Dir: "",
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := unmarshal(&src); err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.Proxies = src.Proxies
|
|
|
|
c.Dir = src.Dir
|
|
|
|
|
|
|
|
if src.Dir != "" {
|
|
|
|
proxies, err := loadBootstrapDir(string(src.Dir))
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "could not load bootstrap dir '%s'", src.Dir)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.Proxies = overrideProxies(c.Proxies, proxies)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type BootstrapProxyConfig struct {
|
2024-04-12 16:41:11 +02:00
|
|
|
Enabled InterpolatedBool `yaml:"enabled"`
|
|
|
|
Weight InterpolatedInt `yaml:"weight"`
|
|
|
|
To InterpolatedString `yaml:"to"`
|
|
|
|
From InterpolatedStringSlice `yaml:"from"`
|
|
|
|
Layers map[store.LayerName]BootstrapLayerConfig `yaml:"layers"`
|
|
|
|
Recreate InterpolatedBool `yaml:"recreate"`
|
2024-03-26 17:28:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
type BootstrapLayerConfig struct {
|
|
|
|
Enabled InterpolatedBool `yaml:"enabled"`
|
|
|
|
Type InterpolatedString `yaml:"type"`
|
|
|
|
Weight InterpolatedInt `yaml:"weight"`
|
|
|
|
Options InterpolatedMap `yaml:"options"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewDefaultBootstrapConfig() BootstrapConfig {
|
|
|
|
return BootstrapConfig{
|
2024-04-05 10:30:34 +02:00
|
|
|
Dir: "",
|
|
|
|
LockTimeout: *NewInterpolatedDuration(30 * time.Second),
|
|
|
|
MaxConnectionRetries: 10,
|
2024-03-26 17:28:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func loadBootstrapDir(dir string) (map[store.ProxyName]BootstrapProxyConfig, error) {
|
|
|
|
pattern := filepath.Join(dir, "*.yml")
|
|
|
|
|
|
|
|
files, err := filepath.Glob(pattern)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
proxies := make(map[store.ProxyName]BootstrapProxyConfig)
|
|
|
|
for _, f := range files {
|
2024-06-28 17:44:51 +02:00
|
|
|
proxy, err := loadBootstrappedProxyConfig(f)
|
2024-03-26 17:28:38 +01:00
|
|
|
if err != nil {
|
2024-06-28 17:44:51 +02:00
|
|
|
return nil, errors.Wrapf(err, "could not load proxy bootstrap file '%s'", f)
|
2024-03-26 17:28:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
name := store.ProxyName(strings.TrimSuffix(filepath.Base(f), filepath.Ext(f)))
|
2024-06-28 17:44:51 +02:00
|
|
|
proxies[name] = *proxy
|
2024-03-26 17:28:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return proxies, nil
|
|
|
|
}
|
|
|
|
|
2024-06-28 17:44:51 +02:00
|
|
|
func loadBootstrappedProxyConfig(filename string) (*BootstrapProxyConfig, error) {
|
|
|
|
data, err := os.ReadFile(filename)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "could not read file '%s'", filename)
|
|
|
|
}
|
|
|
|
|
|
|
|
proxy := BootstrapProxyConfig{}
|
|
|
|
|
|
|
|
if err := yaml.Unmarshal(data, &proxy); err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "could not unmarshal proxy")
|
|
|
|
}
|
|
|
|
|
|
|
|
return &proxy, nil
|
|
|
|
}
|
|
|
|
|
2024-03-26 17:28:38 +01:00
|
|
|
func overrideProxies(base map[store.ProxyName]BootstrapProxyConfig, proxies map[store.ProxyName]BootstrapProxyConfig) map[store.ProxyName]BootstrapProxyConfig {
|
|
|
|
for name, proxy := range proxies {
|
|
|
|
base[name] = proxy
|
|
|
|
}
|
|
|
|
|
|
|
|
return base
|
|
|
|
}
|