diff --git a/pkg/icingadb/v1/notification.go b/pkg/icingadb/v1/notification.go index e3256ec5..a733605b 100644 --- a/pkg/icingadb/v1/notification.go +++ b/pkg/icingadb/v1/notification.go @@ -9,16 +9,16 @@ type Notification struct { EntityWithChecksum `json:",inline"` EnvironmentMeta `json:",inline"` NameCiMeta `json:",inline"` - HostId types.Binary `json:"host_id"` - ServiceId types.Binary `json:"service_id"` - CommandId types.Binary `json:"command_id"` - TimesBegin types.Int `json:"times_begin"` - TimesEnd types.Int `json:"times_end"` - NotificationInterval uint32 `json:"notification_interval"` - TimeperiodId types.Binary `json:"timeperiod_id"` - States uint8 `json:"states"` - Types uint16 `json:"types"` - ZoneId types.Binary `json:"zone_id"` + HostId types.Binary `json:"host_id"` + ServiceId types.Binary `json:"service_id"` + CommandId types.Binary `json:"command_id"` + TimesBegin types.Int `json:"times_begin"` + TimesEnd types.Int `json:"times_end"` + NotificationInterval uint32 `json:"notification_interval"` + TimeperiodId types.Binary `json:"timeperiod_id"` + States types.NotificationStates `json:"states"` + Types types.NotificationTypes `json:"types"` + ZoneId types.Binary `json:"zone_id"` } type NotificationUser struct { diff --git a/pkg/icingadb/v1/user.go b/pkg/icingadb/v1/user.go index 96e61688..4bdf5b93 100644 --- a/pkg/icingadb/v1/user.go +++ b/pkg/icingadb/v1/user.go @@ -9,14 +9,14 @@ type User struct { EntityWithChecksum `json:",inline"` EnvironmentMeta `json:",inline"` NameCiMeta `json:",inline"` - DisplayName string `json:"display_name"` - Email string `json:"email"` - Pager string `json:"pager"` - NotificationsEnabled types.Bool `json:"notifications_enabled"` - TimeperiodId types.Binary `json:"timeperiod_id"` - States uint8 `json:"states"` - Types uint16 `json:"types"` - ZoneId types.Binary `json:"zone_id"` + DisplayName string `json:"display_name"` + Email string `json:"email"` + Pager string `json:"pager"` + NotificationsEnabled types.Bool `json:"notifications_enabled"` + TimeperiodId types.Binary `json:"timeperiod_id"` + States types.NotificationStates `json:"states"` + Types types.NotificationTypes `json:"types"` + ZoneId types.Binary `json:"zone_id"` } type UserCustomvar struct { diff --git a/pkg/types/notification_states.go b/pkg/types/notification_states.go new file mode 100644 index 00000000..ab3ce589 --- /dev/null +++ b/pkg/types/notification_states.go @@ -0,0 +1,76 @@ +package types + +import ( + "database/sql/driver" + "encoding/json" + "fmt" +) + +// NotificationStates specifies the set of states a notification may be sent for. +type NotificationStates uint8 + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (nst *NotificationStates) UnmarshalJSON(bytes []byte) error { + var states []string + if err := json.Unmarshal(bytes, &states); err != nil { + return err + } + + var n NotificationStates + for _, state := range states { + if v, ok := notificationStateNames[state]; ok { + n |= v + } else { + return BadNotificationStates{states} + } + } + + *nst = n + return nil +} + +// Value implements the driver.Valuer interface. +func (nst NotificationStates) Value() (driver.Value, error) { + if nst&^allNotificationStates == 0 { + return int64(nst), nil + } else { + return nil, BadNotificationStates{nst} + } +} + +// BadNotificationStates complains about syntactically, but not semantically valid NotificationStates. +type BadNotificationStates struct { + States interface{} +} + +// Error implements the error interface. +func (bns BadNotificationStates) Error() string { + return fmt.Sprintf("bad notification states: %#v", bns.States) +} + +// notificationStateNames maps all valid NotificationStates values to their SQL representation. +var notificationStateNames = map[string]NotificationStates{ + "OK": 1, + "Warning": 2, + "Critical": 4, + "Unknown": 8, + "Up": 16, + "Down": 32, +} + +// allNotificationStates is the largest valid NotificationStates value. +var allNotificationStates = func() NotificationStates { + var nt NotificationStates + for _, v := range notificationStateNames { + nt |= v + } + + return nt +}() + +// Assert interface compliance. +var ( + _ error = BadNotificationStates{} + _ json.Unmarshaler = (*NotificationStates)(nil) + _ driver.Valuer = NotificationStates(0) +) diff --git a/pkg/types/notification_types.go b/pkg/types/notification_types.go new file mode 100644 index 00000000..f6b8714f --- /dev/null +++ b/pkg/types/notification_types.go @@ -0,0 +1,79 @@ +package types + +import ( + "database/sql/driver" + "encoding/json" + "fmt" +) + +// NotificationTypes specifies the set of reasons a notification may be sent for. +type NotificationTypes uint16 + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (nt *NotificationTypes) UnmarshalJSON(bytes []byte) error { + var types []string + if err := json.Unmarshal(bytes, &types); err != nil { + return err + } + + var n NotificationTypes + for _, typ := range types { + if v, ok := notificationTypeNames[typ]; ok { + n |= v + } else { + return BadNotificationTypes{types} + } + } + + *nt = n + return nil +} + +// Value implements the driver.Valuer interface. +func (nt NotificationTypes) Value() (driver.Value, error) { + if nt&^allNotificationTypes == 0 { + return int64(nt), nil + } else { + return nil, BadNotificationTypes{nt} + } +} + +// BadNotificationTypes complains about syntactically, but not semantically valid NotificationTypes. +type BadNotificationTypes struct { + Types interface{} +} + +// Error implements the error interface. +func (bnt BadNotificationTypes) Error() string { + return fmt.Sprintf("bad notification types: %#v", bnt.Types) +} + +// notificationTypeNames maps all valid NotificationTypes values to their SQL representation. +var notificationTypeNames = map[string]NotificationTypes{ + "DowntimeStart": 1, + "DowntimeEnd": 2, + "DowntimeRemoved": 4, + "Custom": 8, + "Acknowledgement": 16, + "Problem": 32, + "Recovery": 64, + "FlappingStart": 128, + "FlappingEnd": 256, +} + +// allNotificationTypes is the largest valid NotificationTypes value. +var allNotificationTypes = func() NotificationTypes { + var nt NotificationTypes + for _, v := range notificationTypeNames { + nt |= v + } + + return nt +}() + +// Assert interface compliance. +var ( + _ error = BadNotificationTypes{} + _ json.Unmarshaler = (*NotificationTypes)(nil) + _ driver.Valuer = NotificationTypes(0) +)