Skip to content

Commit ac586a2

Browse files
committed
feat: notification watchdog
1 parent 17f5ab4 commit ac586a2

14 files changed

Lines changed: 214 additions & 34 deletions

api/event.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import (
88
"github.com/google/uuid"
99
)
1010

11+
// A dummy event that lives only within the application (never in the event queue)
12+
const EventWatchdog = "notification.watchdog"
13+
1114
// List of all sync events in the `event_queue` table.
1215
//
1316
// These events are generated by the database in response to updates on some of the tables.

api/v1/notification_types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ type NotificationSpec struct {
115115
// It uses the repeat interval as the window for suppression
116116
// as well as the wait for period.
117117
Inhibitions []NotificationInihibition `json:"inhibitions,omitempty"`
118+
119+
// WatchdogInterval is the interval at a watchdog notification is sent.
120+
// A watchdog notification contains the statistics of this notification.
121+
//
122+
// Format: duration string (e.g., "30s", "2m")
123+
WatchdogInterval *string `json:"watchdogInterval,omitempty"`
118124
}
119125

120126
type NotificationInihibition struct {

api/v1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/server.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func launchKopper(ctx context.Context) {
8383
}
8484

8585
if v1.NotificationReconciler, err = kopper.SetupReconciler(ctx, mgr,
86-
db.PersistNotificationFromCRD,
86+
PersistNotificationFromCRD,
8787
db.DeleteNotification,
8888
db.DeleteStaleNotification,
8989
"notification.mission-control.flanksource.com",
@@ -159,6 +159,14 @@ func launchKopper(ctx context.Context) {
159159
}
160160
}
161161

162+
func PersistNotificationFromCRD(ctx context.Context, obj *v1.Notification) error {
163+
if err := db.PersistNotificationFromCRD(ctx, obj); err != nil {
164+
return err
165+
}
166+
167+
return notification.SyncWatchdogJob(ctx, jobs.FuncScheduler, string(obj.GetUID()), obj.Spec.WatchdogInterval)
168+
}
169+
162170
var Serve = &cobra.Command{
163171
Use: "serve",
164172
PreRun: PreRun,

config/crds/mission-control.flanksource.com_notifications.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,6 +1380,13 @@ spec:
13801380
Only applies to Kubernetes health notifications and cannot be turned off.
13811381
Defaults to 30s.
13821382
1383+
Format: duration string (e.g., "30s", "2m")
1384+
type: string
1385+
watchdogInterval:
1386+
description: |-
1387+
WatchdogInterval is the interval at a watchdog notification is sent.
1388+
A watchdog notification contains the statistics of this notification.
1389+
13831390
Format: duration string (e.g., "30s", "2m")
13841391
type: string
13851392
required:

config/schemas/notification.schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,10 @@
362362
},
363363
"type": "array",
364364
"description": "Inhibit controls notification suppression for related resources.\nIt uses the repeat interval as the window for suppression\nas well as the wait for period."
365+
},
366+
"watchdogInterval": {
367+
"type": "string",
368+
"description": "WatchdogInterval is the interval at a watchdog notification is sent.\nA watchdog notification contains the statistics of this notification.\n\nFormat: duration string (e.g., \"30s\", \"2m\")"
365369
}
366370
},
367371
"additionalProperties": false,

db/notifications.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ func PersistNotificationFromCRD(ctx context.Context, obj *v1.Notification) error
7676
}
7777
}
7878

79+
if obj.Spec.WatchdogInterval != nil && *obj.Spec.WatchdogInterval != "" {
80+
if parsed, err := text.ParseDuration(*obj.Spec.WatchdogInterval); err != nil {
81+
return err
82+
} else {
83+
dbObj.WatchdogInterval = parsed
84+
}
85+
}
86+
7987
if len(obj.Spec.GroupBy) > 0 && obj.Spec.WaitFor != nil && *obj.Spec.WaitFor == "" {
8088
return fmt.Errorf("groupBy provided with an empty waitFor. either remove the groupBy or set a waitFor period")
8189
}

go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ require (
8888
go.opentelemetry.io/otel/trace v1.43.0
8989
golang.org/x/sync v0.20.0
9090
google.golang.org/genai v1.34.0
91-
gorm.io/hints v1.1.2
9291
k8s.io/api v0.35.2
9392
)
9493

go.sum

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -894,10 +894,6 @@ github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+Ei
894894
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
895895
github.com/mattn/go-runewidth v0.0.20 h1:WcT52H91ZUAwy8+HUkdM3THM6gXqXuLJi9O3rjcQQaQ=
896896
github.com/mattn/go-runewidth v0.0.20/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
897-
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
898-
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
899-
github.com/mattn/go-sqlite3 v1.14.30 h1:bVreufq3EAIG1Quvws73du3/QgdeZ3myglJlrzSYYCY=
900-
github.com/mattn/go-sqlite3 v1.14.30/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
901897
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
902898
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
903899
github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE=
@@ -1754,18 +1750,12 @@ gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg=
17541750
gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo=
17551751
gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4=
17561752
gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo=
1757-
gorm.io/driver/sqlite v1.5.0/go.mod h1:kDMDfntV9u/vuMmz8APHtHF0b4nyBB7sfCieC6G8k8I=
1758-
gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
1759-
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
17601753
gorm.io/driver/sqlserver v1.6.3 h1:UR+nWCuphPnq7UxnL57PSrlYjuvs+sf1N59GgFX7uAI=
17611754
gorm.io/driver/sqlserver v1.6.3/go.mod h1:VZeNn7hqX1aXoN5TPAFGWvxWG90xtA8erGn2gQmpc6U=
1762-
gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
17631755
gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
17641756
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
17651757
gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
17661758
gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
1767-
gorm.io/hints v1.1.2 h1:b5j0kwk5p4+3BtDtYqqfY+ATSxjj+6ptPgVveuynn9o=
1768-
gorm.io/hints v1.1.2/go.mod h1:/ARdpUHAtyEMCh5NNi3tI7FsGh+Cj/MIUlvNxCNCFWg=
17691759
gorm.io/plugin/dbresolver v1.6.2 h1:F4b85TenghUeITqe3+epPSUtHH7RIk3fXr5l83DF8Pc=
17701760
gorm.io/plugin/dbresolver v1.6.2/go.mod h1:tctw63jdrOezFR9HmrKnPkmig3m5Edem9fdxk9bQSzM=
17711761
gorm.io/plugin/prometheus v0.1.0 h1:kDQwAfCUsT9D6jDUpIp7pnc7bCJu/6voM8I/BmFjxUQ=

jobs/jobs.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ func Start(ctx context.Context, mcpServer *server.MCPServer) {
110110
shutdown.ShutdownAndExit(1, fmt.Sprintf("failed to schedule job SyncCRDStatusJob: %v", err))
111111
}
112112

113+
if err := notification.InitWatchdogNotifications(ctx, FuncScheduler); err != nil {
114+
shutdown.ShutdownAndExit(1, fmt.Sprintf("failed to schedule job InitWatchdogNotifications: %v", err))
115+
}
116+
113117
if err := notification.InitCRDStatusUpdates(ctx); err != nil {
114118
logger.Errorf("failed to start notification status update queue: %v", err)
115119
}

0 commit comments

Comments
 (0)