From 1aeacd0d1b1d573527eadfda8354ae69dd652d42 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Thu, 26 Sep 2024 17:18:32 +0200 Subject: [PATCH] Implement support for notification types - add new flag "-t" for notification types to matrix-host-notification and matrix-service-notification - implement value validation for HostState and ServiceState --- cmd/matrix-host-notification/main.go | 3 +- cmd/matrix-service-notification/main.go | 5 +- internal/icinga2/messages.go | 11 ++-- internal/icinga2/parameters.go | 70 +++++++++++++++++++++++-- internal/matrix/constants.go | 1 + internal/matrix/message.go | 1 + 6 files changed, 81 insertions(+), 10 deletions(-) diff --git a/cmd/matrix-host-notification/main.go b/cmd/matrix-host-notification/main.go index cc92d5c..ca846cb 100644 --- a/cmd/matrix-host-notification/main.go +++ b/cmd/matrix-host-notification/main.go @@ -45,9 +45,10 @@ func parseFlags() *icinga2.HostParameters { flag.StringVar(&config.LongDateTime, "d", "", "long date time ($icinga.long_date_time$)") flag.StringVar(&config.Hostname, "l", "", "hostname ($host.name$)") flag.StringVar(&config.HostDisplayName, "n", "", "host display name ($host.display_name$)") + flag.Var(&config.NotificationType, "t", "notification type ($notification_type$)") flag.StringVar(&config.HostOutput, "o", "", "host output ($host.output$)") - flag.StringVar(&config.HostState, "s", "", "host state ($host.state$)") + flag.Var(&config.HostState, "s", "host state ($host.state$)") flag.StringVar(&config.MatrixRoom, "m", "", "matrix room ($notification_matrix_room$)") flag.Var(&config.MatrixServer, "x", "matrix server ($notification_matrix_server$)") diff --git a/cmd/matrix-service-notification/main.go b/cmd/matrix-service-notification/main.go index dfb7e80..2194726 100644 --- a/cmd/matrix-service-notification/main.go +++ b/cmd/matrix-service-notification/main.go @@ -13,6 +13,8 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . + +// The main package for matrix-service-notification package main import ( @@ -45,11 +47,12 @@ func parseFlags() *icinga2.ServiceParameters { flag.StringVar(¶meters.LongDateTime, "d", "", "long date time ($icinga.long_date_time$)") flag.StringVar(¶meters.Hostname, "l", "", "hostname ($host.name$)") flag.StringVar(¶meters.HostDisplayName, "n", "", "host display name ($host.display_name$)") + flag.Var(¶meters.NotificationType, "t", "notification type ($notification_type$)") flag.StringVar(¶meters.ServiceName, "e", "", "service name ($service.name$)") flag.StringVar(¶meters.ServiceDisplayName, "u", "", "service display name ($service.display_name$)") flag.StringVar(¶meters.ServiceOutput, "o", "", "service output ($service.output$)") - flag.StringVar(¶meters.ServiceState, "s", "", "service state ($service.state$)") + flag.Var(¶meters.ServiceState, "s", "service state ($service.state$)") flag.StringVar(¶meters.MatrixRoom, "m", "", "matrix room ($notification_matrix_room$)") flag.Var(¶meters.MatrixServer, "x", "matrix server ($notification_matrix_server$)") diff --git a/internal/icinga2/messages.go b/internal/icinga2/messages.go index f6edc87..7ef7c20 100644 --- a/internal/icinga2/messages.go +++ b/internal/icinga2/messages.go @@ -13,6 +13,7 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . + package icinga2 import ( @@ -84,10 +85,11 @@ func BuildHostNotification(p *HostParameters) (string, error) { if _, err := fmt.Fprintf( message, - "%s HOST: %s is %s!
\n"+ + "%s [%s] HOST: %s is %s!
\n"+ "When: %s
\n"+ "Info: %s
\n", - getIcon(p.HostState), + getIcon(string(p.HostState)), + p.NotificationType, p.HostDisplayName, p.HostState, p.LongDateTime, p.HostOutput); err != nil { return "", CouldNotWriteToBufferErr{err} @@ -118,10 +120,11 @@ func BuildServiceNotification(p *ServiceParameters) (string, error) { if _, err := fmt.Fprintf( message, - "%s Service: %s on %s is %s.
\n"+ + "%s [%s] Service: %s on %s is %s.
\n"+ "When: %s
\n"+ "Info: %s
\n", - getIcon(p.ServiceState), p.ServiceDisplayName, p.HostDisplayName, + getIcon(string(p.ServiceState)), p.NotificationType, + p.ServiceDisplayName, p.HostDisplayName, p.ServiceState, p.LongDateTime, p.ServiceOutput, ); err != nil { return "", CouldNotWriteToBufferErr{err} diff --git a/internal/icinga2/parameters.go b/internal/icinga2/parameters.go index ef1ac76..a2cc01d 100644 --- a/internal/icinga2/parameters.go +++ b/internal/icinga2/parameters.go @@ -13,12 +13,14 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . + package icinga2 import ( "errors" "fmt" "net/url" + "strings" ) type URLValue struct { @@ -44,6 +46,65 @@ func (u *URLValue) String() string { return "" } +type HostStateValue string + +func (v *HostStateValue) Set(value string) error { + if strings.EqualFold(value, "Up") || strings.EqualFold(value, "Down") { + *v = HostStateValue(strings.ToUpper(value)) + + return nil + } + + return fmt.Errorf("invalid host state value: %s", value) +} + +func (v *HostStateValue) String() string { + return string(*v) +} + +type ServiceStateValue string + +func (v *ServiceStateValue) Set(value string) error { + allowedValues := []string{"OK", "Warning", "Critical", "Unknown"} + + for _, allowed := range allowedValues { + if strings.EqualFold(value, allowed) { + *v = ServiceStateValue(strings.ToUpper(value)) + + return nil + } + } + + return fmt.Errorf("invalid service state value: %s", value) +} + +func (v *ServiceStateValue) String() string { + return string(*v) +} + +type NotificationTypeValue string + +func (v *NotificationTypeValue) Set(value string) error { + allowedValues := []string{ + "DowntimeStart", "DowntimeEnd", "DownTimeRemoved", "Custom", "Acknowledgement", "Problem", "Recovery", + "FlappingStart", "FlappingEnd", + } + + for _, allowed := range allowedValues { + if strings.EqualFold(value, allowed) { + *v = NotificationTypeValue(strings.ToUpper(value)) + + return nil + } + } + + return fmt.Errorf("invalid notification type value: %s", value) +} + +func (v *NotificationTypeValue) String() string { + return string(*v) +} + type MatrixParameters struct { MatrixRoom string MatrixServer URLValue @@ -51,12 +112,13 @@ type MatrixParameters struct { } func (m *MatrixParameters) HasRequired() bool { - return m.MatrixRoom != "" && m.MatrixServer.URL != nil && m.MatrixToken != "" + return !(m.MatrixRoom == "" || m.MatrixServer.URL == nil || m.MatrixToken == "") } type BaseParameters struct { NotificationAuthorName string NotificationComment string + NotificationType NotificationTypeValue IcingaWeb2URL URLValue LongDateTime string Hostname string @@ -66,12 +128,12 @@ type BaseParameters struct { } func (p BaseParameters) HasRequired() bool { - return p.LongDateTime != "" && p.Hostname != "" && p.HostDisplayName != "" + return !(p.LongDateTime == "" || p.Hostname == "" || p.HostDisplayName == "" || p.NotificationType == "") } type HostParameters struct { HostOutput string - HostState string + HostState HostStateValue BaseParameters MatrixParameters } @@ -89,7 +151,7 @@ type ServiceParameters struct { ServiceName string ServiceDisplayName string ServiceOutput string - ServiceState string + ServiceState ServiceStateValue BaseParameters MatrixParameters } diff --git a/internal/matrix/constants.go b/internal/matrix/constants.go index 7b9aaa2..20a4168 100644 --- a/internal/matrix/constants.go +++ b/internal/matrix/constants.go @@ -13,6 +13,7 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . + package matrix const ( diff --git a/internal/matrix/message.go b/internal/matrix/message.go index d2b21bf..83acd56 100644 --- a/internal/matrix/message.go +++ b/internal/matrix/message.go @@ -13,6 +13,7 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . + package matrix import (