MCPcopy
hub / github.com/crowdsecurity/crowdsec / CreateOrUpdateAlert

Method CreateOrUpdateAlert

pkg/database/alerts.go:45–187  ·  view source on GitHub ↗

CreateOrUpdateAlert is specific to PAPI : It checks if alert already exists, otherwise inserts it if alert already exists, it checks it associated decisions already exists if some associated decisions are missing (ie. previous insert ended up in error) it inserts them

(ctx context.Context, machineID string, alertItem *models.Alert)

Source from the content-addressed store, hash-verified

43// if alert already exists, it checks it associated decisions already exists
44// if some associated decisions are missing (ie. previous insert ended up in error) it inserts them
45func (c *Client) CreateOrUpdateAlert(ctx context.Context, machineID string, alertItem *models.Alert) (string, error) {
46 if alertItem.UUID == "" {
47 return "", errors.New("alert UUID is empty")
48 }
49
50 alerts, err := c.Ent.Alert.Query().Where(alert.UUID(alertItem.UUID)).WithDecisions().All(ctx)
51 if err != nil && !ent.IsNotFound(err) {
52 return "", fmt.Errorf("unable to query alerts for uuid %s: %w", alertItem.UUID, err)
53 }
54
55 // alert wasn't found, insert it (expected hotpath)
56 if ent.IsNotFound(err) || len(alerts) == 0 {
57 alertIDs, err := c.CreateAlert(ctx, machineID, []*models.Alert{alertItem})
58 if err != nil {
59 return "", fmt.Errorf("unable to create alert: %w", err)
60 }
61
62 // happy nilaway
63 if len(alertIDs) == 0 {
64 return "", fmt.Errorf("unable to create alert: no IDs returned for alert %s", alertItem.UUID)
65 }
66
67 return alertIDs[0], nil
68 }
69
70 // this should never happen
71 if len(alerts) > 1 {
72 return "", fmt.Errorf("multiple alerts found for uuid %s", alertItem.UUID)
73 }
74
75 log.Infof("Alert %s already exists, checking associated decisions", alertItem.UUID)
76
77 // alert is found, check for any missing decisions
78
79 newUuids := make([]string, len(alertItem.Decisions))
80 for i, decItem := range alertItem.Decisions {
81 newUuids[i] = decItem.UUID
82 }
83
84 foundAlert := alerts[0]
85 foundUuids := make([]string, len(foundAlert.Edges.Decisions))
86
87 for i, decItem := range foundAlert.Edges.Decisions {
88 foundUuids[i] = decItem.UUID
89 }
90
91 sort.Strings(foundUuids)
92 sort.Strings(newUuids)
93
94 missingUuids := []string{}
95
96 for idx, uuid := range newUuids {
97 if len(foundUuids) < idx+1 || uuid != foundUuids[idx] {
98 log.Warningf("Decision with uuid %s not found in alert %s", uuid, foundAlert.UUID)
99 missingUuids = append(missingUuids, uuid)
100 }
101 }
102

Callers 1

AlertCmdFunction · 0.80

Calls 15

CreateAlertMethod · 0.95
SizeMethod · 0.95
UUIDFunction · 0.92
IsNotFoundFunction · 0.92
NewRangeFunction · 0.92
WithDecisionsMethod · 0.80
StringsMethod · 0.80
AllMethod · 0.45
WhereMethod · 0.45
QueryMethod · 0.45
ParseMethod · 0.45
AddMethod · 0.45

Tested by

no test coverage detected