Skip to content

Commit 3c76ed8

Browse files
committed
Allow to mute Object/Incident via specific events
1 parent 7cdb7f5 commit 3c76ed8

14 files changed

+307
-115
lines changed

internal/event/event.go

+12
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ type Event struct {
3434
Username string `json:"username"`
3535
Message string `json:"message"`
3636

37+
Mute types.Bool `json:"mute"`
38+
MuteReason string `json:"mute_reason"`
39+
3740
ID int64 `json:"-"`
3841
}
3942

@@ -64,6 +67,9 @@ func (e *Event) Validate() error {
6467
if e.Severity != SeverityNone && e.Type != TypeState {
6568
return fmt.Errorf("invalid event: if 'severity' is set, 'type' must be set to %q", TypeState)
6669
}
70+
if e.Mute.Valid && e.Mute.Bool && e.MuteReason == "" {
71+
return fmt.Errorf("invalid event: 'mute_reason' must not be empty if 'mute' is set")
72+
}
6773

6874
switch e.Type {
6975
case "":
@@ -84,6 +90,12 @@ func (e *Event) Validate() error {
8490
}
8591
}
8692

93+
// SetMute alters the event mute and mute reason.
94+
func (e *Event) SetMute(muted bool, reason string) {
95+
e.Mute = types.Bool{Valid: true, Bool: muted}
96+
e.MuteReason = reason
97+
}
98+
8799
func (e *Event) String() string {
88100
return fmt.Sprintf("[time=%s type=%q severity=%s]", e.Time, e.Type, e.Severity.String())
89101
}

internal/icinga2/api_responses.go

+32-30
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,16 @@ type CheckResult struct {
8585
//
8686
// NOTE:
8787
// - An empty Service field indicates a host downtime.
88+
// - If a downtime was added by a ScheduledDowntime object, ConfigOwner is set to the name of that object and can
89+
// only be cancelled by its owner. Otherwise, it is empty and indicates user-created downtimes (via API or/and UI).
8890
//
8991
// https://icinga.com/docs/icinga-2/latest/doc/09-object-types/#objecttype-downtime
9092
type Downtime struct {
91-
Host string `json:"host_name"`
92-
Service string `json:"service_name"`
93-
Author string `json:"author"`
94-
Comment string `json:"comment"`
93+
Host string `json:"host_name"`
94+
Service string `json:"service_name"`
95+
Author string `json:"author"`
96+
Comment string `json:"comment"`
97+
ConfigOwner string `json:"config_owner"`
9598

9699
// RemoveTime is used to indicate whether a downtime was ended automatically or cancelled prematurely by a user.
97100
// It is set to zero time for the former case, otherwise to the timestamp at which time has been cancelled.
@@ -133,6 +136,7 @@ type HostServiceRuntimeAttributes struct {
133136
LastStateChange UnixFloat `json:"last_state_change"`
134137
DowntimeDepth int `json:"downtime_depth"`
135138
Acknowledgement int `json:"acknowledgement"`
139+
IsFlapping bool `json:"flapping"`
136140
AcknowledgementLastChange UnixFloat `json:"acknowledgement_last_change"`
137141
}
138142

@@ -179,40 +183,32 @@ type StateChange struct {
179183
CheckResult CheckResult `json:"check_result"`
180184
DowntimeDepth int `json:"downtime_depth"`
181185
Acknowledgement bool `json:"acknowledgement"`
186+
187+
// There is no such json key in the Icinga 2 API streams for state change events, so exclude it.
188+
// This is going to be set/unset manually within this icinga2 package.
189+
IsFlapping bool `json:"-"`
182190
}
183191

184-
// AcknowledgementSet represents the Icinga 2 API Event Stream AcknowledgementSet response for acknowledgements set on hosts/services.
192+
// Acknowledgement represents the Icinga 2 API Event Stream AcknowledgementSet or AcknowledgementCleared
193+
// response for acknowledgements set/cleared on/from hosts/services.
185194
//
186195
// NOTE:
187196
// - An empty Service field indicates a host acknowledgement.
188197
// - State might be StateHost{Up,Down} for hosts or StateService{Ok,Warning,Critical,Unknown} for services.
189198
// - StateType might be StateTypeSoft or StateTypeHard.
199+
// - EventType is either set to typeAcknowledgementSet or typeAcknowledgementCleared
190200
//
191201
// https://icinga.com/docs/icinga-2/latest/doc/12-icinga2-api/#event-stream-type-acknowledgementset
192-
type AcknowledgementSet struct {
202+
// https://icinga.com/docs/icinga-2/latest/doc/12-icinga2-api/#event-stream-type-acknowledgementcleared
203+
type Acknowledgement struct {
193204
Timestamp UnixFloat `json:"timestamp"`
194205
Host string `json:"host"`
195206
Service string `json:"service"`
196207
State int `json:"state"`
197208
StateType int `json:"state_type"`
198209
Author string `json:"author"`
199210
Comment string `json:"comment"`
200-
}
201-
202-
// AcknowledgementCleared represents the Icinga 2 API Event Stream AcknowledgementCleared response for acknowledgements cleared on hosts/services.
203-
//
204-
// NOTE:
205-
// - An empty Service field indicates a host acknowledgement.
206-
// - State might be StateHost{Up,Down} for hosts or StateService{Ok,Warning,Critical,Unknown} for services.
207-
// - StateType might be StateTypeSoft or StateTypeHard.
208-
//
209-
// https://icinga.com/docs/icinga-2/latest/doc/12-icinga2-api/#event-stream-type-acknowledgementcleared
210-
type AcknowledgementCleared struct {
211-
Timestamp UnixFloat `json:"timestamp"`
212-
Host string `json:"host"`
213-
Service string `json:"service"`
214-
State int `json:"state"`
215-
StateType int `json:"state_type"`
211+
EventType string `json:"type"`
216212
}
217213

218214
// CommentAdded represents the Icinga 2 API Event Stream CommentAdded response for added host/service comments.
@@ -267,13 +263,21 @@ type DowntimeTriggered struct {
267263
//
268264
// NOTE:
269265
// - An empty Service field indicates a host being in flapping state.
266+
// - State includes the current state of the Checkable at the point in time at which it enters or exits the flapping state.
267+
// - CurrentFlapping indicates the current flapping value of a Checkable in percent.
268+
// - ThresholdLow is the low/min flapping threshold value set by the user (CurrentFlapping < ThresholdLow = flapping end).
269+
// - ThresholdHigh is the high/max flapping threshold value set by the user (CurrentFlapping > ThresholdHigh = flapping start).
270270
//
271271
// https://icinga.com/docs/icinga-2/latest/doc/12-icinga2-api/#event-stream-type-flapping
272272
type Flapping struct {
273-
Timestamp UnixFloat `json:"timestamp"`
274-
Host string `json:"host"`
275-
Service string `json:"service"`
276-
IsFlapping bool `json:"is_flapping"`
273+
Timestamp UnixFloat `json:"timestamp"`
274+
Host string `json:"host"`
275+
Service string `json:"service"`
276+
IsFlapping bool `json:"is_flapping"`
277+
State int `json:"state"`
278+
CurrentFlapping int `json:"current_flapping"`
279+
ThresholdLow int `json:"threshold_low"`
280+
ThresholdHigh int `json:"threshold_high"`
277281
}
278282

279283
// CheckableCreatedDeleted represents the Icinga 2 API stream Checkable created/deleted response.
@@ -339,10 +343,8 @@ func UnmarshalEventStreamResponse(bytes []byte) (any, error) {
339343
switch responseType {
340344
case typeStateChange:
341345
resp = new(StateChange)
342-
case typeAcknowledgementSet:
343-
resp = new(AcknowledgementSet)
344-
case typeAcknowledgementCleared:
345-
resp = new(AcknowledgementCleared)
346+
case typeAcknowledgementSet, typeAcknowledgementCleared:
347+
resp = new(Acknowledgement)
346348
case typeCommentAdded:
347349
resp = new(CommentAdded)
348350
case typeCommentRemoved:

internal/icinga2/api_responses_test.go

+15-10
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,13 @@ func TestObjectQueriesResult_UnmarshalJSON(t *testing.T) {
180180
Name: "docker-master!load!c27b27c2-e0ab-45ff-8b9b-e95f29851eb0",
181181
Type: "Downtime",
182182
Attrs: Downtime{
183-
Host: "docker-master",
184-
Service: "load",
185-
Author: "icingaadmin",
186-
Comment: "Scheduled downtime for backup",
187-
RemoveTime: UnixFloat(time.UnixMilli(0)),
188-
IsFixed: true,
183+
Host: "docker-master",
184+
Service: "load",
185+
Author: "icingaadmin",
186+
Comment: "Scheduled downtime for backup",
187+
ConfigOwner: "docker-master!load!backup-downtime",
188+
RemoveTime: UnixFloat(time.UnixMilli(0)),
189+
IsFixed: true,
189190
},
190191
},
191192
},
@@ -373,47 +374,51 @@ func TestApiResponseUnmarshal(t *testing.T) {
373374
{
374375
name: "acknowledgementset-host",
375376
jsonData: `{"acknowledgement_type":1,"author":"icingaadmin","comment":"working on it","expiry":0,"host":"dummy-805","notify":true,"persistent":false,"state":1,"state_type":1,"timestamp":1697201074.579106,"type":"AcknowledgementSet"}`,
376-
expected: &AcknowledgementSet{
377+
expected: &Acknowledgement{
377378
Timestamp: UnixFloat(time.UnixMicro(1697201074579106)),
378379
Host: "dummy-805",
379380
State: StateHostDown,
380381
StateType: StateTypeHard,
381382
Author: "icingaadmin",
382383
Comment: "working on it",
384+
EventType: typeAcknowledgementSet,
383385
},
384386
},
385387
{
386388
name: "acknowledgementset-service",
387389
jsonData: `{"acknowledgement_type":1,"author":"icingaadmin","comment":"will be fixed soon","expiry":0,"host":"docker-master","notify":true,"persistent":false,"service":"ssh","state":2,"state_type":1,"timestamp":1697201107.64792,"type":"AcknowledgementSet"}`,
388-
expected: &AcknowledgementSet{
390+
expected: &Acknowledgement{
389391
Timestamp: UnixFloat(time.UnixMicro(1697201107647920)),
390392
Host: "docker-master",
391393
Service: "ssh",
392394
State: StateServiceCritical,
393395
StateType: StateTypeHard,
394396
Author: "icingaadmin",
395397
Comment: "will be fixed soon",
398+
EventType: typeAcknowledgementSet,
396399
},
397400
},
398401
{
399402
name: "acknowledgementcleared-host",
400403
jsonData: `{"acknowledgement_type":0,"host":"dummy-805","state":1,"state_type":1,"timestamp":1697201082.440148,"type":"AcknowledgementCleared"}`,
401-
expected: &AcknowledgementCleared{
404+
expected: &Acknowledgement{
402405
Timestamp: UnixFloat(time.UnixMicro(1697201082440148)),
403406
Host: "dummy-805",
404407
State: StateHostDown,
405408
StateType: StateTypeHard,
409+
EventType: typeAcknowledgementCleared,
406410
},
407411
},
408412
{
409413
name: "acknowledgementcleared-service",
410414
jsonData: `{"acknowledgement_type":0,"host":"docker-master","service":"ssh","state":2,"state_type":1,"timestamp":1697201110.220349,"type":"AcknowledgementCleared"}`,
411-
expected: &AcknowledgementCleared{
415+
expected: &Acknowledgement{
412416
Timestamp: UnixFloat(time.UnixMicro(1697201110220349)),
413417
Host: "docker-master",
414418
Service: "ssh",
415419
State: StateServiceCritical,
416420
StateType: StateTypeHard,
421+
EventType: typeAcknowledgementCleared,
417422
},
418423
},
419424
{

0 commit comments

Comments
 (0)