From 4b0f943bd7934a9850619e96cf61028ba33a9e06 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sun, 19 Apr 2026 22:55:39 -0600 Subject: [PATCH] feat: add Blacklist type to check-ip-blacklist to test ergonomics --- .../cmd/check-ip-blacklist/blacklist.go | 72 +++++++++++++++++++ net/ipcohort/cmd/check-ip-blacklist/main.go | 42 +++-------- 2 files changed, 82 insertions(+), 32 deletions(-) create mode 100644 net/ipcohort/cmd/check-ip-blacklist/blacklist.go diff --git a/net/ipcohort/cmd/check-ip-blacklist/blacklist.go b/net/ipcohort/cmd/check-ip-blacklist/blacklist.go new file mode 100644 index 0000000..6f106dd --- /dev/null +++ b/net/ipcohort/cmd/check-ip-blacklist/blacklist.go @@ -0,0 +1,72 @@ +package main + +import ( + "context" + "fmt" + "os" + "path/filepath" + "sync/atomic" + "time" + + "github.com/therootcompany/golib/net/gitshallow" + "github.com/therootcompany/golib/net/ipcohort" +) + +type Blacklist struct { + atomic.Pointer[ipcohort.Cohort] + path string + repo *gitshallow.Repo // nil if file-only +} + +func NewBlacklist(path string) *Blacklist { + return &Blacklist{path: path} +} + +func NewGitBlacklist(gitURL, path string) *Blacklist { + repo := gitshallow.New(gitURL, filepath.Dir(path), 1, "") + b := &Blacklist{path: path, repo: repo} + repo.Register(b.reload) + return b +} + +func (b *Blacklist) Init(lightGC bool) error { + if b.repo != nil { + return b.repo.Init(lightGC) + } + return b.reload() +} + +func (b *Blacklist) Run(ctx context.Context, lightGC bool) { + ticker := time.NewTicker(47 * time.Minute) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + if updated, err := b.repo.Sync(lightGC); err != nil { + fmt.Fprintf(os.Stderr, "error: blacklist sync: %v\n", err) + } else if updated { + fmt.Fprintf(os.Stderr, "blacklist: reloaded %d entries\n", b.Size()) + } + case <-ctx.Done(): + return + } + } +} + +func (b *Blacklist) Contains(ipStr string) bool { + return b.Load().Contains(ipStr) +} + +func (b *Blacklist) Size() int { + return b.Load().Size() +} + +func (b *Blacklist) reload() error { + c, err := ipcohort.LoadFile(b.path) + if err != nil { + return err + } + b.Store(c) + return nil +} diff --git a/net/ipcohort/cmd/check-ip-blacklist/main.go b/net/ipcohort/cmd/check-ip-blacklist/main.go index 6293849..50a4133 100644 --- a/net/ipcohort/cmd/check-ip-blacklist/main.go +++ b/net/ipcohort/cmd/check-ip-blacklist/main.go @@ -3,11 +3,6 @@ package main import ( "fmt" "os" - "path/filepath" - "sync/atomic" - - "github.com/therootcompany/golib/net/gitshallow" - "github.com/therootcompany/golib/net/ipcohort" ) func main() { @@ -23,38 +18,21 @@ func main() { gitURL = os.Args[3] } - var cohort atomic.Pointer[ipcohort.Cohort] - - load := func() error { - c, err := ipcohort.LoadFile(dataPath) - if err != nil { - return err - } - cohort.Store(c) - return nil - } - + var bl *Blacklist if gitURL != "" { - repoDir := filepath.Dir(dataPath) - repo := gitshallow.New(gitURL, repoDir, 1, "") - repo.Register(load) - fmt.Fprintf(os.Stderr, "Syncing %q ...\n", repoDir) - if err := repo.Init(false); err != nil { - fmt.Fprintf(os.Stderr, "error: git sync: %v\n", err) - os.Exit(1) - } + bl = NewGitBlacklist(gitURL, dataPath) } else { - fmt.Fprintf(os.Stderr, "Loading %q ...\n", dataPath) - if err := load(); err != nil { - fmt.Fprintf(os.Stderr, "error: load: %v\n", err) - os.Exit(1) - } + bl = NewBlacklist(dataPath) } - c := cohort.Load() - fmt.Fprintf(os.Stderr, "Loaded %d entries\n", c.Size()) + if err := bl.Init(false); err != nil { + fmt.Fprintf(os.Stderr, "error: %v\n", err) + os.Exit(1) + } - if c.Contains(ipStr) { + fmt.Fprintf(os.Stderr, "Loaded %d entries\n", bl.Size()) + + if bl.Contains(ipStr) { fmt.Printf("%s is BLOCKED\n", ipStr) os.Exit(1) }