From f3aa7685bf5d903e6c0f1767803df814d616c1fb Mon Sep 17 00:00:00 2001 From: Thanatat Tamtan Date: Sat, 11 Jul 2026 08:16:27 +0700 Subject: [PATCH 1/2] add waf events subcommand Renders waf.events (recent sampled firewall match events, newest first) via WAFEventsResult.Table(): TIME, ACTION, RULE, IP, COUNTRY, METHOD, HOST, PATH. Flags: -rule (short id filter), -action (log|allow|block), -limit (default 50, max 200), -before (keyset cursor from a previous response's next). Pins github.com/deploys-app/api to branch waf-events (380d9eb5c22f6de251183f2220fbd9ff089b8932); re-pin to the next api tag after the api PR merges. --- go.mod | 2 +- go.sum | 4 ++-- internal/runner/help.go | 1 + internal/runner/waf.go | 10 ++++++++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index bbbf001..cd4d7c9 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/deploys-app/deploys go 1.26 require ( - github.com/deploys-app/api v0.0.0-20260713024420-a04c48ceccc7 + github.com/deploys-app/api v0.0.0-20260714032625-fb28c7d02fcd github.com/moonrhythm/toon v0.0.0-20260702100246-6fcdad0a6a12 golang.org/x/mod v0.37.0 golang.org/x/oauth2 v0.14.0 diff --git a/go.sum b/go.sum index 042f14e..d878b5b 100644 --- a/go.sum +++ b/go.sum @@ -9,8 +9,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:W github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deploys-app/api v0.0.0-20260713024420-a04c48ceccc7 h1:7ecexsz+To+O0+NNPAfDI7hLgHabTjS48I8n/5TKvLw= -github.com/deploys-app/api v0.0.0-20260713024420-a04c48ceccc7/go.mod h1:X70UJs5awlRV4Cmn0FPJAgEbn4N933K8YgSKc1y9aD8= +github.com/deploys-app/api v0.0.0-20260714032625-fb28c7d02fcd h1:q1fIyT4RvpzCxxOpaLseENsNpbQEupvAtsS7uo89/ZQ= +github.com/deploys-app/api v0.0.0-20260714032625-fb28c7d02fcd/go.mod h1:X70UJs5awlRV4Cmn0FPJAgEbn4N933K8YgSKc1y9aD8= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= diff --git a/internal/runner/help.go b/internal/runner/help.go index 3a2d190..8f24110 100644 --- a/internal/runner/help.go +++ b/internal/runner/help.go @@ -194,6 +194,7 @@ var commands = []command{ {name: "list", short: "list WAF zones in a project"}, {name: "set", args: "-f [-description]", short: "apply a WAF zone from a YAML spec"}, {name: "delete", short: "delete the WAF zone"}, + {name: "events", args: "[-rule ] [-action log|allow|block] [-limit n] [-before ]", short: "show recent sampled firewall match events"}, {name: "metrics", args: "[-time-range 1h|6h|12h|1d|7d|30d]", short: "show WAF request metrics"}, {name: "limitmetrics", args: "[-time-range 1h|6h|12h|1d|7d|30d]", short: "show WAF rate-limit metrics"}, }, diff --git a/internal/runner/waf.go b/internal/runner/waf.go index 19a7446..d185dd3 100644 --- a/internal/runner/waf.go +++ b/internal/runner/waf.go @@ -83,6 +83,16 @@ func (rn Runner) waf(args ...string) error { f.StringVar(&req.Location, "location", "", "location") f.Parse(args[1:]) resp, err = s.Delete(context.Background(), &req) + case "events": + var req api.WAFEvents + f.StringVar(&req.Project, "project", "", "project id") + f.StringVar(&req.Location, "location", "", "location") + f.StringVar(&req.RuleID, "rule", "", "rule id filter (short id from waf get)") + f.StringVar(&req.Action, "action", "", "action filter: log, allow, block") + f.StringVar(&req.Before, "before", "", "page cursor from a previous response's next") + f.IntVar(&req.Limit, "limit", 0, "max events per page (default 50, max 200)") + f.Parse(args[1:]) + resp, err = s.Events(context.Background(), &req) case "metrics": var ( req api.WAFMetrics From 3d84c19144f9e472b2cea6316ed70e399ec06568 Mon Sep 17 00:00:00 2001 From: Thanatat Tamtan Date: Sat, 11 Jul 2026 08:39:25 +0700 Subject: [PATCH 2/2] print next page cursor after events table Table mode drops WAFEventsResult.Next (no cursor column), leaving a table-mode user with no way to obtain the -before value. Print a one-line 'next: ' trailer when more pages exist; structured output modes already carry the field in the payload. --- internal/runner/waf.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/internal/runner/waf.go b/internal/runner/waf.go index d185dd3..c92f2fc 100644 --- a/internal/runner/waf.go +++ b/internal/runner/waf.go @@ -92,7 +92,19 @@ func (rn Runner) waf(args ...string) error { f.StringVar(&req.Before, "before", "", "page cursor from a previous response's next") f.IntVar(&req.Limit, "limit", 0, "max events per page (default 50, max 200)") f.Parse(args[1:]) - resp, err = s.Events(context.Background(), &req) + r, rerr := s.Events(context.Background(), &req) + if rerr != nil { + return rerr + } + if perr := rn.print(r); perr != nil { + return perr + } + // Table() carries no cursor column, so without this trailer a + // table-mode user has no way to obtain the -before value. + if (rn.OutputMode == "" || rn.OutputMode == "table") && r.Next != "" { + fmt.Fprintf(rn.output(), "next: %s\n", r.Next) + } + return nil case "metrics": var ( req api.WAFMetrics