Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions central/metrics/aggregator/alerts/tracker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package alerts

import (
"context"
"iter"
"strconv"
"strings"

"github.com/prometheus/client_golang/prometheus"
alertDS "github.com/stackrox/rox/central/alert/datastore"
"github.com/stackrox/rox/central/metrics/aggregator/common"
v1 "github.com/stackrox/rox/generated/api/v1"
"github.com/stackrox/rox/generated/storage"
)

var getters = []common.LabelGetter[*finding]{
// Alert
{Label: "Cluster", Getter: func(f *finding) string { return f.GetClusterName() }},
{Label: "Namespace", Getter: func(f *finding) string { return f.GetNamespace() }},
{Label: "Resource", Getter: func(f *finding) string { return f.GetResource().GetName() }},
{Label: "Deployment", Getter: func(f *finding) string { return f.GetDeployment().GetName() }},
{Label: "IsDeploymentActive", Getter: func(f *finding) string { return strconv.FormatBool(!f.GetDeployment().GetInactive()) }},
{Label: "IsPlatformComponent", Getter: func(f *finding) string { return strconv.FormatBool(f.GetPlatformComponent()) }},
{Label: "Policy", Getter: func(f *finding) string { return f.GetPolicy().GetName() }},
{Label: "Categories", Getter: func(f *finding) string { return strings.Join(f.GetPolicy().GetCategories(), ",") }},
{Label: "Severity", Getter: func(f *finding) string { return f.GetPolicy().GetSeverity().String() }},
{Label: "Action", Getter: func(f *finding) string { return f.GetEnforcement().GetAction().String() }},
{Label: "Message", Getter: func(f *finding) string { return f.GetEnforcement().GetMessage() }},
{Label: "Stage", Getter: func(f *finding) string { return f.GetLifecycleStage().String() }},
{Label: "State", Getter: func(f *finding) string { return f.GetState().String() }},
{Label: "Entity", Getter: func(f *finding) string { return f.GetEntityType().String() }},
{Label: "EntityName", Getter: getEntityName},

// Violation
{Label: "Type", Getter: func(f *finding) string { return f.GetType().String() }},
}

type finding struct {
common.OneOrMore
*storage.Alert
*storage.Alert_Violation
}

func MakeTrackerConfig(gauge func(string, prometheus.Labels, int)) *common.TrackerConfig[*finding] {
return common.MakeTrackerConfig(
"alerts",
"aggregated policy violation alerts",
getters,
common.Bind4th(trackAlertsMetrics, alertDS.Singleton()),
gauge)
}

func trackAlertsMetrics(ctx context.Context, query *v1.Query, _ common.MetricsConfiguration, ds alertDS.DataStore) iter.Seq[*finding] {
f := finding{}
return func(yield func(*finding) bool) {
_ = ds.WalkByQuery(ctx, query, func(a *storage.Alert) error {
f.Alert = a
for _, v := range a.GetViolations() {
f.Alert_Violation = v
if !yield(&f) {
return common.ErrStopIterator
}
}
return nil
})
}
}

func getEntityName(f *finding) string {
switch e := f.GetEntity().(type) {
case *storage.Alert_Deployment_:
return e.Deployment.GetName()
case *storage.Alert_Image:
return e.Image.GetName().GetFullName()
case *storage.Alert_Resource_:
return e.Resource.GetName()
}
return ""
}
14 changes: 13 additions & 1 deletion central/metrics/aggregator/singleton.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"github.com/prometheus/client_golang/prometheus"
configDS "github.com/stackrox/rox/central/config/datastore"
"github.com/stackrox/rox/central/metrics"
"github.com/stackrox/rox/central/metrics/aggregator/alerts"
"github.com/stackrox/rox/central/metrics/aggregator/common"
"github.com/stackrox/rox/central/metrics/aggregator/image_vulnerabilities"
"github.com/stackrox/rox/central/metrics/aggregator/node_vulnerabilities"
Expand All @@ -34,6 +35,7 @@

image_vulnerabilities common.Tracker
node_vulnerabilities common.Tracker
alerts common.Tracker
}

func Singleton() interface {
Expand All @@ -52,6 +54,7 @@

image_vulnerabilities: image_vulnerabilities.MakeTrackerConfig(metrics.SetCustomAggregatedCount),
node_vulnerabilities: node_vulnerabilities.MakeTrackerConfig(metrics.SetCustomAggregatedCount),
alerts: alerts.MakeTrackerConfig(metrics.SetCustomAggregatedCount),

Check warning on line 57 in central/metrics/aggregator/singleton.go

View check run for this annotation

Codecov / codecov/patch

central/metrics/aggregator/singleton.go#L57

Added line #L57 was not covered by tests
}
systemPrivateConfig, err := configDS.Singleton().GetPrivateConfig(
sac.WithAllAccess(context.Background()))
Expand Down Expand Up @@ -85,11 +88,20 @@
return err
}
}
{
a := cfg.GetAlerts()
if err := ar.alerts.Reconfigure(ar.registry,
a.GetFilter(),
a.GetMetrics(),
time.Minute*time.Duration(a.GetGatheringPeriodMinutes())); err != nil {
return err
}

Check warning on line 98 in central/metrics/aggregator/singleton.go

View check run for this annotation

Codecov / codecov/patch

central/metrics/aggregator/singleton.go#L91-L98

Added lines #L91 - L98 were not covered by tests
}
return nil
}

func (ar *aggregatorRunner) Start() {
for _, tracker := range []common.Tracker{ar.image_vulnerabilities, ar.node_vulnerabilities} {
for _, tracker := range []common.Tracker{ar.image_vulnerabilities, ar.node_vulnerabilities, ar.alerts} {

Check warning on line 104 in central/metrics/aggregator/singleton.go

View check run for this annotation

Codecov / codecov/patch

central/metrics/aggregator/singleton.go#L104

Added line #L104 was not covered by tests
tracker.Do(func() {
go ar.run(tracker)
})
Expand Down
24 changes: 24 additions & 0 deletions generated/api/v1/config_service.swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading