github.com/safing/portbase@v0.19.5/notifications/module-mirror.go (about) 1 package notifications 2 3 import ( 4 "github.com/safing/portbase/log" 5 "github.com/safing/portbase/modules" 6 ) 7 8 // AttachToModule attaches the notification to a module and changes to the 9 // notification will be reflected on the module failure status. 10 func (n *Notification) AttachToModule(m *modules.Module) { 11 if m == nil { 12 log.Warningf("notifications: invalid usage: cannot attach %s to nil module", n.EventID) 13 return 14 } 15 16 n.lock.Lock() 17 defer n.lock.Unlock() 18 19 if n.State != Active { 20 log.Warningf("notifications: cannot attach module to inactive notification %s", n.EventID) 21 return 22 } 23 if n.belongsTo != nil { 24 log.Warningf("notifications: cannot override attached module for notification %s", n.EventID) 25 return 26 } 27 28 // Attach module. 29 n.belongsTo = m 30 31 // Set module failure status. 32 switch n.Type { //nolint:exhaustive 33 case Info: 34 m.Hint(n.EventID, n.Title, n.Message) 35 case Warning: 36 m.Warning(n.EventID, n.Title, n.Message) 37 case Error: 38 m.Error(n.EventID, n.Title, n.Message) 39 default: 40 log.Warningf("notifications: incompatible type for attaching to module in notification %s", n.EventID) 41 m.Error(n.EventID, n.Title, n.Message+" [incompatible notification type]") 42 } 43 } 44 45 // resolveModuleFailure removes the notification from the module failure status. 46 func (n *Notification) resolveModuleFailure() { 47 if n.belongsTo != nil { 48 // Resolve failure in attached module. 49 n.belongsTo.Resolve(n.EventID) 50 51 // Reset attachment in order to mitigate duplicate failure resolving. 52 // Re-attachment is prevented by the state check when attaching. 53 n.belongsTo = nil 54 } 55 } 56 57 func init() { 58 modules.SetFailureUpdateNotifyFunc(mirrorModuleStatus) 59 } 60 61 func mirrorModuleStatus(moduleFailure uint8, id, title, msg string) { 62 // Ignore "resolve all" requests. 63 if id == "" { 64 return 65 } 66 67 // Get notification from storage. 68 n, ok := getNotification(id) 69 if ok { 70 // The notification already exists. 71 72 // Check if we should delete it. 73 if moduleFailure == modules.FailureNone && !n.Meta().IsDeleted() { 74 75 // Remove belongsTo, as the deletion was already triggered by the module itself. 76 n.Lock() 77 n.belongsTo = nil 78 n.Unlock() 79 80 n.Delete() 81 } 82 83 return 84 } 85 86 // A notification for the given ID does not yet exists, create it. 87 n = &Notification{ 88 EventID: id, 89 Title: title, 90 Message: msg, 91 AvailableActions: []*Action{ 92 { 93 Text: "Get Help", 94 Type: ActionTypeOpenURL, 95 Payload: "https://safing.io/support/", 96 }, 97 }, 98 } 99 100 switch moduleFailure { 101 case modules.FailureNone: 102 return 103 case modules.FailureHint: 104 n.Type = Info 105 n.AvailableActions = nil 106 case modules.FailureWarning: 107 n.Type = Warning 108 n.ShowOnSystem = true 109 case modules.FailureError: 110 n.Type = Error 111 n.ShowOnSystem = true 112 } 113 114 Notify(n) 115 }