mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 21:11:30 +00:00
875f433c52
Before this fix, RunScan declared `scanErrors []string` but never
appended to it. As a result:
- the summary Info log ("network target scan completed") always
reported `"errors": 0`, regardless of how many endpoints failed
- the DiscoveryReport's `Errors` field — stored on the scan record
and surfaced in the GUI scan history — was always nil
Operators who needed to understand scan failures had to enable Debug
logging and grep through the noise of expected sweep-scan connection
refusals. The per-endpoint log level (Debug) is deliberate and correct
— scanning a /24 typically produces 200+ connection-refused results,
and logging each at Warn would create massive log spam at default
verbosity. The bug was the silent loss of the aggregate count.
This commit:
- extracts the partitioning logic into `collectScanResults`, a pure
method that splits per-endpoint results into discovered certificate
entries and a list of endpoint error strings
- populates the errors list with "<address>: <error>" so the scan
record correlates failures back to specific endpoints
- preserves the existing Debug-level per-endpoint log (sweep noise
discipline) — no change to default-verbosity log output
The summary Info log's "errors" field and the DiscoveryReport's Errors
field now reflect the true failure count. Debug detail remains
available for operators diagnosing specific endpoints.
Audit scope note: the M-9 finding narrative implied broad Debug-level
hiding of real errors across AWS SM, Azure KV, GCP SM, and network
scan sentinel agents. On investigation, the three cloud-discovery
connectors (awssm, azurekv, gcpsm) already use appropriate Warn/Error
discipline for per-item and root-level failures. Only the network
scanner had a silent observability gap, and it was a missed append
rather than a misapplied log level. See audit resolution log for
full details.
CWE: CWE-778 (Insufficient Logging) — aggregate failure count lost.
Tests: 4 new unit tests on collectScanResults covering the
aggregation path (success + failure mix), all-success, all-failed,
and empty-input degenerate cases. All tests pass with -race.
Verification:
- go build ./cmd/server/... ./cmd/agent/... ./cmd/mcp-server/... ./cmd/cli/... exit 0
- go vet ./... exit 0
- go test -race -count=1 -timeout 300s [full CI race path] exit 0
- golangci-lint run ./... --timeout 5m (v2.11.4) 0 issues
- govulncheck ./... (@latest) 0 in-code vulnerabilities
- go test -count=1 -cover ./internal/service/... 68.0% (> 55% threshold)
Invariants preserved:
- collectScanResults signature: method on *NetworkScanService,
input []domain.NetworkScanResult, return ([]DiscoveredCertEntry, []string)
- Debug log key names unchanged ("address", "error")
- DiscoveryReport schema unchanged (Errors field already existed)
- Sentinel agent ID "server-scanner" unchanged
- No migration, no API, no wire-format change
Refs: M-9 Medium finding; audit resolution log appended in follow-up
commit on workspace-level audit report.