Registry and Analytics: run, subnet, direction and protocol filters, successes-by-target chart
Registry (/registry):
- filters by run (slice by the address's cycle in that run), subnet
(drop-down of configured subnets), direction (egress/ingress) and
protocol (icmp, tcp, ssh, https, tls); status in scope is computed over
the narrowed checks
- chart "successful checks per target (egress) / site (ingress)" when both
direction and protocol are chosen; a row opens the list of addresses
(dialog, CSV)
- API: direction/protocol parameters and run in GET /admin/registry,
GET /admin/registry/breakdown and /breakdown/list
- subnet filter passes ids as one JSON parameter (SQLite variable limit)
Analytics (/analytics):
- subnet filter recomputes the whole page over the addresses of the run
inside the subnet; only their checks are read; cache per run and subnet
- direction and protocol focus the page; with both set the registry chart
is shown
- subnet parameter in GET /admin/analytics/runs/{id} and lists (JSON, CSV)
Docs: plans and summaries in docs/changes, README, API, USAGE.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
068c10ea1c
commit
ded196ec8d
40 files changed
+2545
-188
No files matched your search
@@ -2,12 +2,14 @@ package analytics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/netip"
|
||||
|
||||
"cloudipvalidator/internal/db"
|
||||
)
|
||||
|
||||
// Load reads a finished run from the database and computes its analysis.
|
||||
func Load(ctx context.Context, d *db.DB, runID int64) (*Analysis, error) {
|
||||
// Load reads a finished run from the database and computes its analysis,
|
||||
// narrowed to subnet unless that is the zero prefix.
|
||||
func Load(ctx context.Context, d *db.DB, runID int64, subnet netip.Prefix) (*Analysis, error) {
|
||||
run, err := d.GetRun(ctx, runID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -32,8 +34,19 @@ func Load(ctx context.Context, d *db.DB, runID int64) (*Analysis, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// With a subnet only the checks of its addresses are read; Compute narrows
|
||||
// the results by the same rule.
|
||||
var ids []int64
|
||||
if subnet.IsValid() {
|
||||
ids = []int64{}
|
||||
for _, r := range results {
|
||||
if ip, err := netip.ParseAddr(r.IPAddress); err == nil && subnet.Contains(ip) {
|
||||
ids = append(ids, r.RegistryID)
|
||||
}
|
||||
}
|
||||
}
|
||||
return Compute(Input{
|
||||
Run: *run, Results: results, Subnets: subnets, SiteNames: names, Rechecked: rechecked,
|
||||
Each: func(fn func(db.RunCheck)) error { return d.EachRunCheck(ctx, runID, fn) },
|
||||
Run: *run, Results: results, Subnets: subnets, SiteNames: names, Rechecked: rechecked, Subnet: subnet,
|
||||
Each: func(fn func(db.RunCheck)) error { return d.EachRunCheck(ctx, runID, ids, fn) },
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user