usage_alerts.go raw
1 package alerting
2
3 import (
4 "encoding/json"
5 "fmt"
6 )
7
8 // ValidationError creates a formatted validation error
9 func ValidationError(msg string) error {
10 return fmt.Errorf("validation error: %s", msg)
11 }
12
13 // AlertTypeAccount is the alert type for account-scoped alerts
14 const AlertTypeAccount = "account"
15
16 // UsageSubtypes defines all supported usage alert subtypes
17 var UsageSubtypes = struct {
18 QueryUsage string
19 RecordUsage string
20 ChinaQueryUsage string
21 RumDecisionUsage string
22 FilterChainUsage string
23 MonitorUsage string
24 }{
25 QueryUsage: "query_usage",
26 RecordUsage: "record_usage",
27 ChinaQueryUsage: "china_query_usage",
28 RumDecisionUsage: "rum_decision_usage",
29 FilterChainUsage: "filter_chain_usage",
30 MonitorUsage: "monitor_usage",
31 }
32
33 // AllowedUsageSubtypes is a map of valid usage alert subtypes
34 var AllowedUsageSubtypes = map[string]bool{
35 UsageSubtypes.QueryUsage: true,
36 UsageSubtypes.RecordUsage: true,
37 UsageSubtypes.ChinaQueryUsage: true,
38 UsageSubtypes.RumDecisionUsage: true,
39 UsageSubtypes.FilterChainUsage: true,
40 UsageSubtypes.MonitorUsage: true,
41 }
42
43 // UsageAlertData contains the threshold percentage for usage alerts
44 type UsageAlertData struct {
45 AlertAtPercent int `json:"alert_at_percent"`
46 }
47
48 // NewUsageAlert creates a new account usage alert
49 func NewUsageAlert(name string, subtype string, alertAtPercent int, notifierListIds []string) *Alert {
50 accountType := AlertTypeAccount
51 return &Alert{
52 Name: &name,
53 Type: &accountType,
54 Subtype: &subtype,
55 Data: MarshalUsageAlertData(UsageAlertData{AlertAtPercent: alertAtPercent}),
56 NotifierListIds: notifierListIds,
57 ZoneNames: []string{},
58 }
59 }
60
61 // MarshalUsageAlertData converts UsageAlertData to JSON for the Alert.Data field
62 func MarshalUsageAlertData(data UsageAlertData) json.RawMessage {
63 jsonData, _ := json.Marshal(data)
64 return jsonData
65 }
66
67 // UnmarshalUsageAlertData extracts UsageAlertData from an Alert
68 func UnmarshalUsageAlertData(alert *Alert) (UsageAlertData, error) {
69 if alert.Data == nil {
70 return UsageAlertData{}, fmt.Errorf("alert data is nil")
71 }
72
73 var data UsageAlertData
74 err := json.Unmarshal(alert.Data, &data)
75 return data, err
76 }
77
78 // ValidateUsageAlert validates a usage alert configuration
79 func ValidateUsageAlert(alert *Alert) error {
80 if alert.Type == nil || *alert.Type != AlertTypeAccount {
81 return fmt.Errorf("type must be 'account'")
82 }
83
84 if alert.Subtype == nil {
85 return fmt.Errorf("subtype is required")
86 }
87
88 if _, ok := AllowedUsageSubtypes[*alert.Subtype]; !ok {
89 return fmt.Errorf("invalid subtype %q", *alert.Subtype)
90 }
91
92 data, err := UnmarshalUsageAlertData(alert)
93 if err != nil {
94 return fmt.Errorf("invalid data format: %v", err)
95 }
96
97 if data.AlertAtPercent < 1 || data.AlertAtPercent > 100 {
98 return fmt.Errorf("data.alert_at_percent must be between 1 and 100")
99 }
100
101 if alert.Name == nil || *alert.Name == "" {
102 return fmt.Errorf("name is required")
103 }
104
105 return nil
106 }
107