1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
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
}
|