fleet/server/webhooks/vulnerabilities.go
Nico e8152e53fc
Log response body in PostJSONWithTimeout error case (#40509)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
# Checklist for submitter


- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

## Testing

- [ ] QA'd all new/changed functionality manually
2026-02-25 15:35:29 -06:00

75 lines
2 KiB
Go

package webhooks
import (
"context"
"log/slog"
"net/url"
"time"
"github.com/fleetdm/fleet/v4/server"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/fleet"
)
// TriggerVulnerabilitiesWebhook performs the webhook requests for vulnerabilities.
func TriggerVulnerabilitiesWebhook(
ctx context.Context,
ds fleet.Datastore,
logger *slog.Logger,
args VulnArgs,
mapper VulnMapper,
) error {
vulnConfig := args.AppConfig.WebhookSettings.VulnerabilitiesWebhook
if !vulnConfig.Enable {
return nil
}
logger.DebugContext(ctx, "vulnerability webhook triggered", "recent_vulns", len(args.Vulnerablities))
serverURL, err := url.Parse(args.AppConfig.ServerSettings.ServerURL)
if err != nil {
return ctxerr.Wrap(ctx, err, "invalid server url")
}
targetURL := vulnConfig.DestinationURL
batchSize := vulnConfig.HostBatchSize
cveGrouped := make(map[string][]uint)
for _, v := range args.Vulnerablities {
cveGrouped[v.GetCVE()] = append(cveGrouped[v.GetCVE()], v.Affected())
}
for cve, sIDs := range cveGrouped {
hosts, err := ds.HostVulnSummariesBySoftwareIDs(ctx, sIDs)
if err != nil {
return ctxerr.Wrap(ctx, err, "get hosts by software ids")
}
for len(hosts) > 0 {
limit := len(hosts)
if batchSize > 0 && len(hosts) > batchSize {
limit = batchSize
}
payload := mapper.GetPayload(serverURL, hosts[:limit], cve, args.Meta[cve])
if err := sendVulnerabilityHostBatch(ctx, targetURL, payload, args.Time, logger); err != nil {
return ctxerr.Wrap(ctx, err, "send vulnerability host batch")
}
hosts = hosts[limit:]
}
}
return nil
}
func sendVulnerabilityHostBatch(ctx context.Context, targetURL string, vuln WebhookPayload, now time.Time, logger *slog.Logger) error {
payload := map[string]interface{}{
"timestamp": now,
"vulnerability": vuln,
}
if err := server.PostJSONWithTimeout(ctx, targetURL, &payload, logger); err != nil {
return ctxerr.Wrapf(ctx, err, "posting to %s", targetURL)
}
return nil
}