-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinterface.go
More file actions
291 lines (227 loc) · 8.81 KB
/
Copy pathinterface.go
File metadata and controls
291 lines (227 loc) · 8.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
// Package gear provides the core gear system for the HAProxy monitoring application.
// It follows the compile-time gear pattern (similar to Caddy) where plugins register
// themselves via init() functions and implement a common Gear interface.
package gear
import (
"context"
"net/http"
"time"
"github.com/a-h/templ"
"github.com/go-chi/chi/v5"
)
// Gear is the main interface that all gears must implement.
// Gears are self-contained modules that provide specific functionality
// to the monitoring application.
type Gear interface {
// Info returns metadata about the gear.
Info() Info
// Initialize is called once when the application starts.
// Gears should set up their internal state and validate configuration.
Initialize(ctx context.Context, deps Dependencies) error
// Start is called after all plugins are initialized.
// Gears should start any background goroutines here.
Start(ctx context.Context) error
// Stop is called during application shutdown.
// Gears should clean up resources and stop background goroutines.
Stop(ctx context.Context) error
// Health returns the current health status of the gear.
Health() HealthStatus
// RegisterRoutes registers HTTP routes for this gear.
// The router is mounted at the gear's base path (e.g., /logs).
RegisterRoutes(r chi.Router)
// SidebarItem returns configuration for this gear's sidebar entry.
// Return nil if the gear should not appear in the sidebar.
SidebarItem() *SidebarConfig
// SettingsPage returns a templ component for the gear's settings page.
// Return nil if the gear has no configurable settings.
// The config parameter contains the gear's current configuration.
SettingsPage(config map[string]any) templ.Component
// Permissions returns the permissions this gear requires.
// These are registered with the permission system on startup.
Permissions() []PermissionDef
// Migrations returns database migrations for this gear.
// Migrations are run in order during application startup.
Migrations() []Migration
}
// Scope describes how a gear relates to monitored boxes. It controls both
// where the gear's row(s) live in the gears table and when the gear is
// shown in the sidebar.
//
// Three values are recognized:
//
// - ScopeBox — the default; one row per (server_id, name) in the
// gears table. The gear is shown in the sidebar only
// when the active box context has it enabled. Examples:
// HAProxy, Metrics, Logs, Services, Certificates,
// Traffic, Alerts, OS Updates.
// - ScopeSystem — a single row keyed by the SystemServerID sentinel;
// the gear is install-wide and is shown in the sidebar
// regardless of which box (if any) is selected.
// Example: the Home dashboard.
// - ScopeBoxAgnostic — a single install-wide row, like ScopeSystem, but
// semantically the gear lists or aggregates *across*
// boxes rather than ignoring boxes entirely. The
// sidebar shows it independent of any box selection,
// and box-specific gears are hidden when no box is
// active (this gear is the place to pick one).
// Example: the Bx (Boxes) fleet view.
type Scope string
const (
// ScopeBox indicates the gear is enabled per-box (default).
ScopeBox Scope = "box"
// ScopeSystem indicates the gear is enabled globally for the whole install.
ScopeSystem Scope = "system"
// ScopeBoxAgnostic indicates the gear is install-wide and lists/aggregates
// across boxes. It is always visible in the sidebar.
ScopeBoxAgnostic Scope = "box_agnostic"
)
// IsBoxScoped reports whether the scope ties the gear to a specific box.
// Box-scoped gears are hidden from the sidebar when no box is selected.
func (s Scope) IsBoxScoped() bool {
return s == "" || s == ScopeBox
}
// Info contains metadata about a gear.
type Info struct {
// Name is the internal identifier (e.g., "logs", "metrics").
// Must be unique across all plugins.
Name string
// DisplayName is shown in the UI (e.g., "System Logs").
DisplayName string
// Description provides a detailed description of the gear.
Description string
// Version is the semantic version (e.g., "1.0.0").
Version string
// Icon is the icon identifier used in the sidebar.
Icon string
// Category groups related plugins (e.g., "monitoring", "security", "system").
Category string
// Author is optional author information.
Author string
// Website is an optional documentation URL.
Website string
// Core indicates this is a core gear that cannot be disabled.
Core bool
// Scope controls whether the gear is per-box or system-wide.
// Empty value is treated as ScopeBox for backward compatibility.
Scope Scope
}
// EffectiveScope returns the Scope, defaulting to ScopeBox when unset.
func (i Info) EffectiveScope() Scope {
if i.Scope == "" {
return ScopeBox
}
return i.Scope
}
// HealthStatus represents the health state of a gear.
type HealthStatus struct {
// Status is one of: "healthy", "degraded", "unhealthy"
Status string
// Message provides additional context about the health status.
Message string
// LastCheck is when the health was last checked.
LastCheck time.Time
}
// Health status constants.
const (
HealthStatusHealthy = "healthy"
HealthStatusDegraded = "degraded"
HealthStatusUnhealthy = "unhealthy"
)
// SidebarConfig defines how a gear appears in the navigation sidebar.
type SidebarConfig struct {
// Path is the URL path (e.g., "/logs").
Path string
// Icon returns the SVG icon component for the sidebar.
Icon templ.Component
// DefaultOrder is the default sort order (lower numbers appear first).
DefaultOrder int
// BadgeProvider returns a badge count (e.g., unread alerts).
// Return 0 to hide the badge.
BadgeProvider func() int
// ShowAlways shows this item even when the gear is disabled.
// Used for core plugins like Dashboard.
ShowAlways bool
// RequiresPermission specifies the permission needed to see this item.
// If empty, visible to all authenticated users.
RequiresPermission string
}
// PermissionDef defines a permission that a gear uses.
type PermissionDef struct {
// Component is the permission component name (e.g., "logs").
Component string
// Actions are the available actions (e.g., "view", "configure", "manage").
Actions []string
// Description is a human-readable description of the permission.
Description string
}
// Migration defines a database migration for a gear.
type Migration struct {
// Version is a sequential version number.
// Migrations are run in version order.
Version int
// Description describes what this migration does.
Description string
// Up is the SQL to apply the migration.
Up string
// Down is the SQL to revert the migration.
Down string
}
// CollectorGear is implemented by plugins that collect data periodically.
type CollectorGear interface {
Gear
// Collectors returns the data collectors provided by this gear.
Collectors() []Collector
}
// Collector defines a periodic data collector.
type Collector struct {
// Name identifies this collector.
Name string
// Interval is how often to run the collector.
Interval time.Duration
// Collect runs the data collection.
// Returns the collected data and any error.
Collect func(ctx context.Context) (any, error)
// OnData is called with collected data.
// Gears can use this to store data or publish events.
OnData func(data any) error
}
// WebSocketGear is implemented by plugins that handle WebSocket connections.
type WebSocketGear interface {
Gear
// WebSocketHandlers returns WebSocket handlers provided by this gear.
WebSocketHandlers() []WebSocketHandler
}
// WebSocketHandler defines a WebSocket endpoint.
type WebSocketHandler struct {
// Path is the WebSocket endpoint path.
Path string
// Handler processes WebSocket connections.
Handler http.HandlerFunc
}
// EventHandlerGear is implemented by gears that react to events.
type EventHandlerGear interface {
Gear
// SubscribedEvents returns the event types this gear handles.
SubscribedEvents() []string
// HandleEvent is called when a subscribed event occurs.
HandleEvent(eventType string, payload any)
}
// SearchableGear is implemented by gears that support global search.
type SearchableGear interface {
Gear
// Search returns results matching the query.
Search(ctx context.Context, query string) ([]SearchResult, error)
}
// SearchResult represents a search result from a gear.
type SearchResult struct {
// Title is the result title.
Title string
// Description provides context about the result.
Description string
// URL is the link to the result.
URL string
// Relevance is a score from 0 to 1.
Relevance float64
// Plugin is the name of the gear that provided this result.
Gear string
}