Files
ss/internal/automation/config.go

48 lines
1.5 KiB
Go

package automation
import (
"fmt"
"gopkg.in/yaml.v3"
"gitea.epss.net.cn/klesh/ss/internal/yamlutil"
)
// ParseConfig converts the raw (already YAML-decoded) `ssm:` block value —
// pulled out of the generic map produced by loading core-config.yaml — into
// a strongly-typed Config, by round-tripping it through YAML.
func ParseConfig(raw interface{}) (*Config, error) {
data, err := yaml.Marshal(raw)
if err != nil {
return nil, fmt.Errorf("failed to marshal ssm config: %w", err)
}
var cfg Config
if err := yamlutil.Unmarshal(data, &cfg); err != nil {
return nil, fmt.Errorf("failed to parse ssm config: %w", err)
}
return &cfg, nil
}
// Apply runs every ssm automation rule against finalConfig (the fully
// merged generated config, with essential/DNS defaults already applied),
// using proxies as the pool collected while merging active subscriptions.
// Each rule/patch is independent: one failing doesn't stop the rest, and
// all failures are returned as non-fatal errors for the caller to log.
func Apply(finalConfig map[string]interface{}, cfg *Config, proxies []ProxyRef) []error {
var errs []error
buildProxyGroups(finalConfig, cfg.ProxyGroups, proxies)
if rateErrs := buildRateFilterGroups(finalConfig, cfg.RateFilters, proxies); len(rateErrs) > 0 {
errs = append(errs, rateErrs...)
}
for _, patch := range cfg.Patches {
if err := applyPatch(finalConfig, patch); err != nil {
errs = append(errs, fmt.Errorf("patch %q: %w", patch.Path, err))
}
}
return errs
}