package source import ( "errors" "fmt" "log/slog" "net/netip" "os" ) // a source that reads the address from a file path. // useful when your record has to be in-sync with // some configured address on your machine. type fileSource struct { log *slog.Logger path string family Family } var _ Source = (*fileSource)(nil) func newFile(log *slog.Logger, cfg Config) (*fileSource, error) { if _, err := os.Stat(cfg.Path); errors.Is(err, os.ErrNotExist) { return nil, fmt.Errorf("cannot access file for source: %w", err) } return &fileSource{log: log, path: cfg.Path, family: cfg.Family}, nil } func (s *fileSource) Supports(f Family) bool { return f == s.family } func (s *fileSource) Lookup(Family) (netip.Addr, error) { s.log.Info( "will look up address from file source", slog.String("path", s.path), slog.String("family", string(s.family)), ) raw, err := os.ReadFile(s.path) if err != nil { return netip.Addr{}, fmt.Errorf("file source read failed: %w", err) } content := string(raw) addr, err := parse(content, s.family) if err != nil { s.log.Error( "source file does not contain address of expected family", slog.String("path", s.path), slog.String("expected", string(s.family)), slog.String("content", content), ) return netip.Addr{}, fmt.Errorf("source file contains bad content: %w", err) } return addr, nil }