Skip to content

Commit 782672f

Browse files
committed
Reintroduce Extra Tags for Events
This reverts commit 79951c4.
1 parent 5771c91 commit 782672f

File tree

15 files changed

+133
-24
lines changed

15 files changed

+133
-24
lines changed

doc/10-Channels.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,16 @@ or if the channel is missing required configuration values.
257257
"host": "dummy-816",
258258
"service": "random fortune"
259259
},
260+
"extra_tags": {
261+
"hostgroup/app-mobile": "",
262+
"hostgroup/department-dev": "",
263+
"hostgroup/env-prod": "",
264+
"hostgroup/location-rome": "",
265+
"servicegroup/app-storage": "",
266+
"servicegroup/department-ps": "",
267+
"servicegroup/env-prod": "",
268+
"servicegroup/location-rome": ""
269+
}
260270
},
261271
"incident": {
262272
"id": 1437,

doc/20-HTTP-API.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ curl -v -u 'source-2:insecureinsecure' -d '@-' 'http://localhost:5680/process-ev
2222
"host": "dummy-809",
2323
"service": "random fortune"
2424
},
25+
"extra_tags": {
26+
"hostgroup/app-container": null,
27+
"hostgroup/department-dev": null,
28+
"hostgroup/env-qa": null,
29+
"hostgroup/location-rome": null,
30+
"servicegroup/app-mail": null,
31+
"servicegroup/department-nms": null,
32+
"servicegroup/env-prod": null,
33+
"servicegroup/location-berlin": null
34+
},
2535
"type": "state",
2636
"severity": "crit",
2737
"username": "",

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require (
99
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6
1010
github.com/emersion/go-smtp v0.24.0
1111
github.com/google/uuid v1.6.0
12-
github.com/icinga/icinga-go-library v0.7.3-0.20251009114908-6d45c759cf95
12+
github.com/icinga/icinga-go-library v0.7.3-0.20251022120618-6600889adc38
1313
github.com/jhillyerd/enmime v1.3.0
1414
github.com/jmoiron/sqlx v1.4.0
1515
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
3535
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
3636
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
3737
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
38-
github.com/icinga/icinga-go-library v0.7.3-0.20251009114908-6d45c759cf95 h1:MvNABMN4t1oSY8KntkWbwaFgbxp0oenHWVtyGnN30Pg=
39-
github.com/icinga/icinga-go-library v0.7.3-0.20251009114908-6d45c759cf95/go.mod h1:nQXvnUNKDpJfOLin9cVveUFmiqipMYkoHo5P8O3kjXs=
38+
github.com/icinga/icinga-go-library v0.7.3-0.20251022120618-6600889adc38 h1:5RNrPZCwvqm2/06i9dUCJtcBV+tR8WgUKtHne2sOaA8=
39+
github.com/icinga/icinga-go-library v0.7.3-0.20251022120618-6600889adc38/go.mod h1:L80M/ufoqFJJjZcdnfsTp6eFl06vm3JuvSWlGcDf708=
4040
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQyktQ5+f3dMVZfwD2KWJUgm7M0gdL9NGr8KA=
4141
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
4242
github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4=

internal/channel/channel.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,10 @@ func (c *Channel) Notify(contact *recipient.Contact, i contracts.Incident, ev *e
179179
req := &plugin.NotificationRequest{
180180
Contact: contactStruct,
181181
Object: &plugin.Object{
182-
Name: object.DisplayName(),
183-
Url: ev.URL,
184-
Tags: object.Tags,
182+
Name: object.DisplayName(),
183+
Url: ev.URL,
184+
Tags: object.Tags,
185+
ExtraTags: object.ExtraTags,
185186
},
186187
Incident: &plugin.Incident{
187188
Id: i.ID(),

internal/event/event.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ func (e *Event) Validate() error {
6666
}
6767
}
6868

69+
for tag := range e.ExtraTags {
70+
if len(tag) > 255 {
71+
return fmt.Errorf(
72+
"invalid event: extra tag %q is too long, at most 255 chars allowed, %d given", tag, len(tag),
73+
)
74+
}
75+
}
76+
6977
if e.SourceId == 0 {
7078
return fmt.Errorf("invalid event: source ID must not be empty")
7179
}
@@ -113,6 +121,14 @@ func (e *Event) FullString() string {
113121
}
114122
_, _ = fmt.Fprintf(&b, "\n")
115123
}
124+
_, _ = fmt.Fprintf(&b, " Extra Tags:\n")
125+
for tag, value := range e.ExtraTags {
126+
_, _ = fmt.Fprintf(&b, " %q", tag)
127+
if value != "" {
128+
_, _ = fmt.Fprintf(&b, " = %q", value)
129+
}
130+
_, _ = fmt.Fprintf(&b, "\n")
131+
}
116132
_, _ = fmt.Fprintf(&b, " Time: %s\n", e.Time)
117133
_, _ = fmt.Fprintf(&b, " SourceId: %d\n", e.SourceId)
118134
if e.Type != baseEv.TypeUnknown {

internal/incident/incidents_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ func makeIncident(ctx context.Context, db *database.DB, t *testing.T, sourceID i
156156
"host": testutils.MakeRandomString(t),
157157
"service": testutils.MakeRandomString(t),
158158
},
159+
ExtraTags: map[string]string{
160+
"hostgroup/database-server": "",
161+
"servicegroup/webserver": "",
162+
},
159163
},
160164
}
161165

internal/object/db_types.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,24 @@ package object
22

33
import "github.com/icinga/icinga-go-library/types"
44

5-
// IdTagRow represents a single database object id tag.
6-
type IdTagRow struct {
5+
// TagRow is a base type for IdTagRow and ExtraTagRow
6+
type TagRow struct {
77
ObjectId types.Binary `db:"object_id"`
88
Tag string `db:"tag"`
99
Value string `db:"value"`
1010
}
1111

12+
// ExtraTagRow represents a single database object extra tag like `hostgroup/foo: null`.
13+
type ExtraTagRow TagRow
14+
15+
// TableName implements the contracts.TableNamer interface.
16+
func (e *ExtraTagRow) TableName() string {
17+
return "object_extra_tag"
18+
}
19+
20+
// IdTagRow represents a single database object id tag.
21+
type IdTagRow TagRow
22+
1223
// TableName implements the contracts.TableNamer interface.
1324
func (e *IdTagRow) TableName() string {
1425
return "object_id_tag"

internal/object/object.go

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,21 @@ type Object struct {
2323
URL types.String `db:"url"`
2424
MuteReason types.String `db:"mute_reason"`
2525

26-
Tags map[string]string `db:"-"`
26+
Tags map[string]string `db:"-"`
27+
ExtraTags map[string]string `db:"-"`
2728

2829
db *database.DB
2930
}
3031

3132
// New creates a new object from the given event.
3233
func New(db *database.DB, ev *event.Event) *Object {
3334
obj := &Object{
34-
SourceID: ev.SourceId,
35-
Name: ev.Name,
36-
db: db,
37-
URL: types.MakeString(ev.URL, types.TransformEmptyStringToNull),
38-
Tags: ev.Tags,
35+
SourceID: ev.SourceId,
36+
Name: ev.Name,
37+
db: db,
38+
URL: types.MakeString(ev.URL, types.TransformEmptyStringToNull),
39+
Tags: ev.Tags,
40+
ExtraTags: ev.ExtraTags,
3941
}
4042
if ev.Mute.Valid && ev.Mute.Bool {
4143
obj.MuteReason = types.String{NullString: sql.NullString{String: ev.MuteReason, Valid: true}}
@@ -79,6 +81,7 @@ func FromEvent(ctx context.Context, db *database.DB, ev *event.Event) (*Object,
7981
} else {
8082
*newObject = *object
8183

84+
newObject.ExtraTags = ev.ExtraTags
8285
newObject.Name = ev.Name
8386
newObject.URL = types.MakeString(ev.URL, types.TransformEmptyStringToNull)
8487
if ev.Mute.Valid {
@@ -104,11 +107,25 @@ func FromEvent(ctx context.Context, db *database.DB, ev *event.Event) (*Object,
104107
}
105108

106109
stmt, _ = db.BuildUpsertStmt(&IdTagRow{})
107-
_, err = tx.NamedExecContext(ctx, stmt, mapToIdTagRows(newObject.ID, ev.Tags))
110+
_, err = tx.NamedExecContext(ctx, stmt, mapToTagRows(newObject.ID, ev.Tags))
108111
if err != nil {
109112
return nil, fmt.Errorf("failed to upsert object id tags: %w", err)
110113
}
111114

115+
extraTag := &ExtraTagRow{ObjectId: newObject.ID}
116+
_, err = tx.NamedExecContext(ctx, `DELETE FROM "object_extra_tag" WHERE "object_id" = :object_id`, extraTag)
117+
if err != nil {
118+
return nil, fmt.Errorf("failed to delete object extra tags: %w", err)
119+
}
120+
121+
if len(ev.ExtraTags) > 0 {
122+
stmt, _ := db.BuildInsertStmt(extraTag)
123+
_, err = tx.NamedExecContext(ctx, stmt, mapToTagRows(newObject.ID, ev.ExtraTags))
124+
if err != nil {
125+
return nil, fmt.Errorf("failed to insert object extra tags: %w", err)
126+
}
127+
}
128+
112129
if err = tx.Commit(); err != nil {
113130
return nil, fmt.Errorf("cannot commit object database transaction: %w", err)
114131
}
@@ -155,6 +172,15 @@ func (o *Object) String() string {
155172
_, _ = fmt.Fprintf(&b, " Source %d:\n", o.SourceID)
156173
_, _ = fmt.Fprintf(&b, " Name: %q\n", o.Name)
157174
_, _ = fmt.Fprintf(&b, " URL: %q\n", o.URL.String)
175+
_, _ = fmt.Fprintf(&b, " Extra Tags:\n")
176+
177+
for tag, value := range o.ExtraTags {
178+
_, _ = fmt.Fprintf(&b, " %q", tag)
179+
if value != "" {
180+
_, _ = fmt.Fprintf(&b, " = %q", value)
181+
}
182+
_, _ = fmt.Fprintf(&b, "\n")
183+
}
158184

159185
return b.String()
160186
}
@@ -193,11 +219,11 @@ func ID(source int64, tags map[string]string) types.Binary {
193219
return h.Sum(nil)
194220
}
195221

196-
// mapToIdTagRows transforms the object tags map to a slice of TagRow struct.
197-
func mapToIdTagRows(objectId types.Binary, tags map[string]string) []*IdTagRow {
198-
var tagRows []*IdTagRow
199-
for key, val := range tags {
200-
tagRows = append(tagRows, &IdTagRow{
222+
// mapToTagRows transforms the object (extra) tags map to a slice of TagRow struct.
223+
func mapToTagRows(objectId types.Binary, extraTags map[string]string) []*TagRow {
224+
var tagRows []*TagRow
225+
for key, val := range extraTags {
226+
tagRows = append(tagRows, &TagRow{
201227
ObjectId: objectId,
202228
Tag: key,
203229
Value: val,

internal/object/objects.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ func restoreObjectsFromQuery(ctx context.Context, db *database.DB, query string,
6161
err := utils.ExecAndApply[Object](ctx, db, query, args, func(o *Object) {
6262
o.db = db
6363
o.Tags = map[string]string{}
64+
o.ExtraTags = map[string]string{}
6465

6566
select {
6667
case objects <- o:
@@ -99,6 +100,14 @@ func restoreObjectsFromQuery(ctx context.Context, db *database.DB, query string,
99100
return errors.Wrap(err, "cannot restore objects ID tags")
100101
}
101102

103+
// Restore object extra tags matching the given object ids
104+
err = utils.ForEachRow[ExtraTagRow](ctx, db, "object_id", ids, func(et *ExtraTagRow) {
105+
objectsMap[et.ObjectId.String()].ExtraTags[et.Tag] = et.Value
106+
})
107+
if err != nil {
108+
return errors.Wrap(err, "cannot restore objects extra tags")
109+
}
110+
102111
cacheMu.Lock()
103112
defer cacheMu.Unlock()
104113

0 commit comments

Comments
 (0)