CLI: shorter, plainer output
Tables name a journal source by its first two units or identifiers; guard test shows 20 matching lines and addresses (--all for all), no /32; Housecarl connection errors without Go's request URL, said once by guard check; status tells "not running" from "no permission"; bans says when there are none; "1 ban lifted". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
96f551be80
commit
b87cc6fb62
5 files changed
+169
-37
No files matched your search
@@ -173,6 +173,28 @@ func Describe(w *config.Watch) string {
|
||||
return "file " + w.File
|
||||
}
|
||||
|
||||
// Short describes a watch's source in a table's few columns: at most
|
||||
// two journal units or identifiers, then how many more.
|
||||
func Short(w *config.Watch) string {
|
||||
switch w.Kind() {
|
||||
case "journal":
|
||||
names := w.Journal.Unit
|
||||
if len(names) == 0 {
|
||||
names = w.Journal.Identifier
|
||||
} else {
|
||||
names = append(append([]string(nil), names...), w.Journal.Identifier...)
|
||||
}
|
||||
s := "journal " + strings.Join(names[:min(len(names), 2)], ", ")
|
||||
if len(names) > 2 {
|
||||
s += fmt.Sprintf(" +%d", len(names)-2)
|
||||
}
|
||||
return s
|
||||
case config.SourceHousecarlDrops:
|
||||
return "Housecarl drops (" + w.Protocol + ")"
|
||||
}
|
||||
return "file " + w.File
|
||||
}
|
||||
|
||||
// loadGroups asks Housecarl how each ban list groups IPv6 addresses, so
|
||||
// bounties are counted as the list bans. A list that can't be read now
|
||||
// counts by /64, its default.
|
||||
@@ -409,7 +431,7 @@ type WatchStatus struct {
|
||||
func (d *Daemon) Status() Status {
|
||||
s := Status{Started: d.started}
|
||||
for _, w := range d.watches {
|
||||
s.Watches = append(s.Watches, WatchStatus{Name: w.Cfg.Name, Source: Describe(w.Cfg), List: w.Cfg.Ban.List, Hits: w.Cfg.Hits,
|
||||
s.Watches = append(s.Watches, WatchStatus{Name: w.Cfg.Name, Source: Short(w.Cfg), List: w.Cfg.Ban.List, Hits: w.Cfg.Hits,
|
||||
Within: w.Cfg.Within.String(), Lines: w.lines.Load(), Matches: w.matches.Load(), Bans: w.bans.Load(), Top: w.Tracker.Top(10, d.Now())})
|
||||
}
|
||||
s.Recent, s.Pending = d.state.Snapshot()
|
||||
|
||||
@@ -27,9 +27,10 @@ const Prefix = "/api/v1"
|
||||
|
||||
// Client talks to one Housecarl.
|
||||
type Client struct {
|
||||
base string
|
||||
token string
|
||||
http *http.Client
|
||||
base string
|
||||
socket string
|
||||
token string
|
||||
http *http.Client
|
||||
}
|
||||
|
||||
// Options say how to reach Housecarl.
|
||||
@@ -72,7 +73,7 @@ func New(o Options) (*Client, error) {
|
||||
}
|
||||
tr.TLSClientConfig = cfg
|
||||
}
|
||||
return &Client{base: base, token: strings.TrimSpace(o.Token), http: &http.Client{Transport: tr, Timeout: timeout}}, nil
|
||||
return &Client{base: base, socket: o.Socket, token: strings.TrimSpace(o.Token), http: &http.Client{Transport: tr, Timeout: timeout}}, nil
|
||||
}
|
||||
|
||||
// Error is an error answer from Housecarl.
|
||||
@@ -89,6 +90,32 @@ func (e *Error) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
// UnreachableError is a request Housecarl never answered: no
|
||||
// connection, a TLS failure, a timeout.
|
||||
type UnreachableError struct {
|
||||
Where string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *UnreachableError) Error() string {
|
||||
err := e.Err
|
||||
var ue *url.Error
|
||||
if errors.As(err, &ue) {
|
||||
err = ue.Err // without the method and the URL with its query
|
||||
}
|
||||
return "Housecarl at " + e.Where + " doesn't answer: " + err.Error()
|
||||
}
|
||||
|
||||
func (e *UnreachableError) Unwrap() error { return e.Err }
|
||||
|
||||
// where is where the client reaches Housecarl, for messages.
|
||||
func (c *Client) where() string {
|
||||
if c.socket != "" {
|
||||
return c.socket
|
||||
}
|
||||
return c.base
|
||||
}
|
||||
|
||||
// Refused reports whether Housecarl refused a request for good: asking
|
||||
// again won't help (a bad request, no permission, an address never
|
||||
// banned). Anything else (no answer, a server error) is worth retrying.
|
||||
@@ -123,7 +150,7 @@ func (c *Client) do(ctx context.Context, method, path string, query url.Values,
|
||||
}
|
||||
resp, err := c.http.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
return &UnreachableError{Where: c.where(), Err: err}
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
data, _ := io.ReadAll(io.LimitReader(resp.Body, 16<<20))
|
||||
|
||||
Reference in new issue
Block a user