p1.1: dynamic self-IP deny (DDNS/trace, keep previous, atomic swap)
Discover WAN via ddns:<host> then trace:<url> before listen. Persist to self_ip.json. Previous addresses stay denied for keep_previous. Failure keeps the last known set. /healthz reports age and source.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
)
|
||||
|
||||
// File is the on-disk /etc/sift/config.toml.
|
||||
type File struct {
|
||||
Listen string `toml:"listen"`
|
||||
UserAgent string `toml:"user_agent"`
|
||||
DenyPrefixes []string `toml:"deny_prefixes"`
|
||||
SelfIP SelfIP `toml:"self_ip"`
|
||||
}
|
||||
|
||||
// SelfIP is the [self_ip] block.
|
||||
type SelfIP struct {
|
||||
Sources []string `toml:"sources"`
|
||||
Interval string `toml:"interval"`
|
||||
KeepPrevious string `toml:"keep_previous"`
|
||||
Path string `toml:"path"`
|
||||
}
|
||||
|
||||
// Load reads path. A missing file returns a zero File and a nil error.
|
||||
func Load(path string) (File, error) {
|
||||
var f File
|
||||
b, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return f, nil
|
||||
}
|
||||
return f, err
|
||||
}
|
||||
if err := toml.Unmarshal(b, &f); err != nil {
|
||||
return File{}, err
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func ParseDuration(s string, def time.Duration) time.Duration {
|
||||
if s == "" {
|
||||
return def
|
||||
}
|
||||
d, err := time.ParseDuration(s)
|
||||
if err != nil {
|
||||
return def
|
||||
}
|
||||
return d
|
||||
}
|
||||
Reference in New Issue
Block a user