Skip to content

Commit

Permalink
Allow flexible id tags
Browse files Browse the repository at this point in the history
  • Loading branch information
sukhwinder33445 authored and julianbrost committed Nov 30, 2023
1 parent b54cec5 commit f4123ad
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 25 deletions.
7 changes: 7 additions & 0 deletions internal/listener/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ func (l *Listener) ProcessEvent(w http.ResponseWriter, req *http.Request) {
_, _ = fmt.Fprintf(w, "cannot parse JSON body: %v\n", err)
return
}

if len(ev.Tags) == 0 {
w.WriteHeader(http.StatusBadRequest)
_, _ = fmt.Fprintln(w, "ignoring invalid event: tags cannot be empty")
return
}

ev.Time = time.Now()

if ev.Severity == event.SeverityNone && ev.Type == "" {
Expand Down
34 changes: 25 additions & 9 deletions internal/object/db_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,33 @@ import (
"github.com/icinga/icingadb/pkg/types"
)

// ExtraTagRow represents a single database object extra tag like `hostgroup/foo: null`.
type ExtraTagRow struct {
// TagRow is a base type for IdTagRow and ExtraTagRow
type TagRow struct {
ObjectId types.Binary `db:"object_id"`
Tag string `db:"tag"`
Value string `db:"value"`
}

// ExtraTagRow represents a single database object extra tag like `hostgroup/foo: null`.
type ExtraTagRow TagRow

// TableName implements the contracts.TableNamer interface.
func (e *ExtraTagRow) TableName() string {
return "object_extra_tag"
}

// IdTagRow represents a single database object id tag.
type IdTagRow TagRow

// TableName implements the contracts.TableNamer interface.
func (e *IdTagRow) TableName() string {
return "object_id_tag"
}

type ObjectRow struct {
ID types.Binary `db:"id"`
SourceID int64 `db:"source_id"`
Name string `db:"name"`
Host string `db:"host"`
Service types.String `db:"service"`
URL types.String `db:"url"`
}

Expand Down Expand Up @@ -56,9 +65,17 @@ func LoadFromDB(ctx context.Context, db *icingadb.DB, id types.Binary) (*Object,
return nil, fmt.Errorf("failed to fetch object: %w", err)
}

tags := map[string]string{"host": objectRow.Host}
if objectRow.Service.Valid {
tags["service"] = objectRow.Service.String
var idTagRows []*IdTagRow
err = db.SelectContext(
ctx, &idTagRows,
db.Rebind(db.BuildSelectStmt(&IdTagRow{}, &IdTagRow{})+` WHERE "object_id" = ?`), id,
)
if err != nil {
return nil, fmt.Errorf("failed to fetch object id tags: %w", err)
}
idTags := map[string]string{}
for _, idTag := range idTagRows {
idTags[idTag.Tag] = idTag.Value
}

var extraTagRows []*ExtraTagRow
Expand All @@ -69,7 +86,6 @@ func LoadFromDB(ctx context.Context, db *icingadb.DB, id types.Binary) (*Object,
if err != nil {
return nil, fmt.Errorf("failed to fetch object extra tags: %w", err)
}

extraTags := map[string]string{}
for _, extraTag := range extraTagRows {
extraTags[extraTag.Tag] = extraTag.Value
Expand All @@ -80,7 +96,7 @@ func LoadFromDB(ctx context.Context, db *icingadb.DB, id types.Binary) (*Object,
ID: id,
Name: objectRow.Name,
URL: objectRow.URL.String,
Tags: tags,
Tags: idTags,
ExtraTags: extraTags,
}
cache[id.String()] = obj
Expand Down
27 changes: 14 additions & 13 deletions internal/object/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,31 +72,32 @@ func FromEvent(ctx context.Context, db *icingadb.DB, ev *event.Event) (*Object,
ID: object.ID,
SourceID: ev.SourceId,
Name: ev.Name,
Host: ev.Tags["host"],
URL: utils.ToDBString(ev.URL),
}

if service, ok := ev.Tags["service"]; ok {
dbObj.Service = utils.ToDBString(service)
}

stmt, _ := object.db.BuildUpsertStmt(&ObjectRow{})
_, err = tx.NamedExecContext(ctx, stmt, dbObj)
if err != nil {
return nil, fmt.Errorf("failed to insert object: %w", err)
}

stmt, _ = object.db.BuildUpsertStmt(&IdTagRow{})
_, err = tx.NamedExecContext(ctx, stmt, mapToTagRows(object.ID, ev.Tags))
if err != nil {
return nil, fmt.Errorf("failed to upsert object id tags: %w", err)
}

extraTag := &ExtraTagRow{ObjectId: object.ID}
_, err = tx.NamedExecContext(ctx, `DELETE FROM "object_extra_tag" WHERE "object_id" = :object_id`, extraTag)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to delete object extra tags: %w", err)
}

if len(ev.ExtraTags) > 0 {
stmt, _ := object.db.BuildInsertStmt(extraTag)
_, err = tx.NamedExecContext(ctx, stmt, mapToExtraTagRows(object.ID, ev.ExtraTags))
_, err = tx.NamedExecContext(ctx, stmt, mapToTagRows(object.ID, ev.ExtraTags))
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to insert object extra tags: %w", err)
}
}

Expand Down Expand Up @@ -258,16 +259,16 @@ func ID(source int64, tags map[string]string) types.Binary {
return h.Sum(nil)
}

// mapToExtraTags transforms the object extra tags map to a slice of ExtraTagRow struct.
func mapToExtraTagRows(objectId types.Binary, extraTags map[string]string) []*ExtraTagRow {
var extraTagRows []*ExtraTagRow
// mapToTagRows transforms the object (extra) tags map to a slice of TagRow struct.
func mapToTagRows(objectId types.Binary, extraTags map[string]string) []*TagRow {
var tagRows []*TagRow
for key, val := range extraTags {
extraTagRows = append(extraTagRows, &ExtraTagRow{
tagRows = append(tagRows, &TagRow{
ObjectId: objectId,
Tag: key,
Value: val,
})
}

return extraTagRows
return tagRows
}
11 changes: 8 additions & 3 deletions schema/pgsql/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,6 @@ CREATE TABLE object (
id bytea NOT NULL, -- SHA256 of identifying tags and the source.id
source_id bigint NOT NULL REFERENCES source(id),
name text NOT NULL,
-- this will probably become more flexible in the future
host text NOT NULL,
service text,

url text,

Expand All @@ -147,6 +144,14 @@ CREATE TABLE object (
CONSTRAINT pk_object PRIMARY KEY (id)
);

CREATE TABLE object_id_tag (
object_id bytea NOT NULL REFERENCES object(id),
tag text NOT NULL,
value text NOT NULL,

CONSTRAINT pk_object_id_tag PRIMARY KEY (object_id, tag)
);

CREATE TABLE object_extra_tag (
object_id bytea NOT NULL REFERENCES object(id),
tag text NOT NULL,
Expand Down
14 changes: 14 additions & 0 deletions schema/pgsql/upgrades/020.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
CREATE TABLE object_id_tag (
object_id bytea NOT NULL REFERENCES object(id),
tag text NOT NULL,
value text NOT NULL,

CONSTRAINT pk_object_id_tag PRIMARY KEY (object_id, tag)
);

INSERT INTO object_id_tag (object_id, tag, value) SELECT id, 'host', host FROM object;
INSERT INTO object_id_tag (object_id, tag, value) SELECT id, 'service', service FROM object WHERE service IS NOT NULL;

ALTER TABLE object
DROP COLUMN host,
DROP COLUMN service;

0 comments on commit f4123ad

Please sign in to comment.