primeiro commit

This commit is contained in:
2026-09-16 00:18:01 -03:00
commit 1a5a446b5c
10 changed files with 472 additions and 0 deletions
+63
View File
@@ -0,0 +1,63 @@
// Package config loads he-dydns configuration from a TOML file.
package config
import (
"fmt"
"os"
"path/filepath"
"github.com/BurntSushi/toml"
)
const DefaultIntervalMinutes = 5
// Entry describes a single Hurricane Electric dynamic DNS hostname to keep updated.
type Entry struct {
Hostname string `toml:"hostname"`
Token string `toml:"token"`
}
// Config is the top-level he-dydns configuration.
type Config struct {
// Interface, if set, restricts address discovery to this network
// interface instead of guessing the public IP via an external service.
Interface string `toml:"interface"`
// IntervalMinutes controls how often updates run in daemon mode.
IntervalMinutes int `toml:"interval_minutes"`
Entries []Entry `toml:"entries"`
}
// DefaultPath returns $HOME/.config/he-dydns/config.toml.
func DefaultPath() (string, error) {
home, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("determining home directory: %w", err)
}
return filepath.Join(home, ".config", "he-dydns", "config.toml"), nil
}
// Load reads and validates the configuration file at path.
func Load(path string) (*Config, error) {
var cfg Config
if _, err := toml.DecodeFile(path, &cfg); err != nil {
return nil, fmt.Errorf("reading config %s: %w", path, err)
}
if len(cfg.Entries) == 0 {
return nil, fmt.Errorf("config %s: no entries defined", path)
}
for i, e := range cfg.Entries {
if e.Hostname == "" {
return nil, fmt.Errorf("config %s: entries[%d] missing hostname", path, i)
}
if e.Token == "" {
return nil, fmt.Errorf("config %s: entries[%d] missing token", path, i)
}
}
if cfg.IntervalMinutes <= 0 {
cfg.IntervalMinutes = DefaultIntervalMinutes
}
return &cfg, nil
}