Merge pull request #18 from lippserd/bugfix/notification-bitmask

Correctly parse notification bitmask types
This commit is contained in:
Eric Lippmann 2021-04-06 10:07:54 +02:00 committed by GitHub
commit cf110d74bf
4 changed files with 173 additions and 18 deletions

View file

@ -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 {

View file

@ -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 {

View file

@ -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)
)

View file

@ -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)
)