Skip to content

Commit

Permalink
add entity types for audit logs
Browse files Browse the repository at this point in the history
  • Loading branch information
ezekg committed Dec 13, 2024
1 parent 198d3ef commit 434acee
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 72 deletions.
22 changes: 22 additions & 0 deletions db/migrations/1734124087_add_entity_types.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- re-add the old column
ALTER TABLE
audit_logs
ADD
COLUMN entity_type TEXT NOT NULL DEFAULT 'unknown';

-- revert data migration
UPDATE
audit_logs
SET
entity_type = CASE
entity_type_id
WHEN 1 THEN 'License'
WHEN 2 THEN 'Node'
END;

-- drop the new column
ALTER TABLE
audit_logs DROP COLUMN entity_type_id;

-- drop the new table
DROP TABLE entity_types;
49 changes: 49 additions & 0 deletions db/migrations/1734124087_add_entity_types.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
-- create entities table
CREATE TABLE entity_types (id TINYINT PRIMARY KEY, name TEXT NOT NULL);

-- insert events
INSERT INTO
entity_types (id, name)
VALUES
(0, 'unknown'),
(1, 'license'),
(2, 'node');

-- rebuild the table with the new schema (this is a workaround for sqlite not supporting ALTER TABLE x ALTER COLUMN y NOT NULL)
CREATE TABLE _audit_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
event_type_id TINYINT NOT NULL REFERENCES event_types (id),
entity_type_id TINYINT NOT NULL REFERENCES entity_types (id),
entity_id TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- copy data from the old table to the new
INSERT INTO
_audit_logs (
id,
event_type_id,
entity_type_id,
entity_id,
created_at
)
SELECT
id,
event_type_id,
CASE
entity_type
WHEN 'License' THEN 1
WHEN 'Node' THEN 2
ELSE 0
END AS entity_type_id,
entity_id,
created_at
FROM
audit_logs;

-- drop the old table
DROP TABLE audit_logs;

-- replace with new table
ALTER TABLE
_audit_logs RENAME TO audit_logs;
8 changes: 4 additions & 4 deletions db/queries/audit_logs.sql
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
-- name: InsertAuditLog :exec
INSERT INTO audit_logs (event_type_id, entity_type, entity_id)
INSERT INTO audit_logs (event_type_id, entity_type_id, entity_id)
VALUES (?, ?, ?);

-- name: GetAuditLogs :many
SELECT id, event_type_id, entity_type, entity_id, created_at
SELECT id, event_type_id, entity_type_id, entity_id, created_at
FROM audit_logs
ORDER BY created_at DESC
LIMIT ?;

-- name: GetAuditLogsByEntity :many
SELECT id, event_type_id, entity_type, entity_id, created_at
SELECT id, event_type_id, entity_type_id, entity_id, created_at
FROM audit_logs
WHERE entity_id = ? AND entity_type = ?
WHERE entity_type_id = ? AND entity_id = ?
ORDER BY created_at DESC;
55 changes: 19 additions & 36 deletions internal/db/audit_logs.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 10 additions & 5 deletions internal/db/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 12 additions & 5 deletions internal/db/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ const (
EventTypeNodeActivated
EventTypeNodePing
EventTypeNodeCulled
EventTypeNodeDeactivated
)

type EntityTypeId int

const (
EntityTypeUnknown EntityTypeId = iota
EntityTypeLicense
EntityTypeNode
)

type Store struct {
Expand Down Expand Up @@ -133,11 +140,11 @@ func (s *Store) GetNodeByFingerprint(ctx context.Context, fingerprint string) (*
return &node, nil
}

func (s *Store) InsertAuditLog(ctx context.Context, eventTypeId EventTypeId, entityType string, entityID string) error {
func (s *Store) InsertAuditLog(ctx context.Context, eventTypeId EventTypeId, entityTypeId EntityTypeId, entityID string) error {
params := InsertAuditLogParams{
EventTypeID: int64(eventTypeId),
EntityType: entityType,
EntityID: entityID,
EventTypeID: int64(eventTypeId),
EntityTypeID: int64(entityTypeId),
EntityID: entityID,
}
return s.queries.InsertAuditLog(ctx, params)
}
Expand Down
29 changes: 7 additions & 22 deletions internal/licenses/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,6 @@ const (
OperationStatusNoLicensesAvailable
)

// FIXME(ezkeg) does sqlc support static tables?
type EventType int

const (
EventTypeUnknown EventType = iota
EventTypeLicenseAdded
EventTypeLicenseRemoved
EventTypeLicenseClaimed
EventTypeLicenseReleased
EventTypeNodeActivated
EventTypeNodePing
EventTypeNodeCulled
EventTypeNodeDeactivated
)

var (
ErrNoLicenses = errors.New("license pool is empty")
ErrLicenseNotFound = errors.New("license not found")
Expand Down Expand Up @@ -127,7 +112,7 @@ func (m *manager) AddLicense(ctx context.Context, licenseFilePath string, licens

// Log audit, but do not fail the operation if it fails
if m.config.EnabledAudit {
if err := m.store.InsertAuditLog(ctx, db.EventTypeLicenseAdded, "license", id); err != nil {
if err := m.store.InsertAuditLog(ctx, db.EventTypeLicenseAdded, db.EntityTypeLicense, id); err != nil {
slog.Debug("failed to insert audit log", "licenseID", id, "error", err)
}
}
Expand All @@ -153,7 +138,7 @@ func (m *manager) RemoveLicense(ctx context.Context, id string) error {

// Log audit, but do not fail the operation if it fails
if m.config.EnabledAudit {
if err := m.store.InsertAuditLog(ctx, db.EventTypeLicenseRemoved, "license", id); err != nil {
if err := m.store.InsertAuditLog(ctx, db.EventTypeLicenseRemoved, db.EntityTypeLicense, id); err != nil {
slog.Debug("failed to insert audit log", "licenseID", id, "error", err)
}
}
Expand Down Expand Up @@ -232,7 +217,7 @@ func (m *manager) ClaimLicense(ctx context.Context, fingerprint string) (*Licens
}

if m.config.EnabledAudit {
if err := m.store.InsertAuditLog(ctx, db.EventTypeNodePing, "license", claimedLicense.ID); err != nil {
if err := m.store.InsertAuditLog(ctx, db.EventTypeNodePing, db.EntityTypeLicense, claimedLicense.ID); err != nil {
slog.Warn("failed to insert audit log", "licenseID", claimedLicense.ID, "error", err)
}
}
Expand Down Expand Up @@ -264,7 +249,7 @@ func (m *manager) ClaimLicense(ctx context.Context, fingerprint string) (*Licens
}

if m.config.EnabledAudit {
if err := m.store.InsertAuditLog(ctx, db.EventTypeLicenseClaimed, "license", newLicense.ID); err != nil {
if err := m.store.InsertAuditLog(ctx, db.EventTypeLicenseClaimed, db.EntityTypeLicense, newLicense.ID); err != nil {
slog.Warn("failed to insert audit log", "licenseID", newLicense.ID, "error", err)
}
}
Expand Down Expand Up @@ -315,7 +300,7 @@ func (m *manager) ReleaseLicense(ctx context.Context, fingerprint string) (*Lice
}

if m.config.EnabledAudit {
if err := m.store.InsertAuditLog(ctx, db.EventTypeLicenseReleased, "license", claimedLicense.ID); err != nil {
if err := m.store.InsertAuditLog(ctx, db.EventTypeLicenseReleased, db.EntityTypeLicense, claimedLicense.ID); err != nil {
slog.Warn("failed to insert audit log", "licenseID", claimedLicense.ID, "error", err)
}
}
Expand All @@ -340,7 +325,7 @@ func (m *manager) fetchOrCreateNode(ctx context.Context, store db.Store, fingerp
}

if m.config.EnabledAudit {
if err := store.InsertAuditLog(ctx, db.EventTypeNodeActivated, "node", strconv.FormatInt(node.ID, 10)); err != nil {
if err := store.InsertAuditLog(ctx, db.EventTypeNodeActivated, db.EntityTypeNode, strconv.FormatInt(node.ID, 10)); err != nil {
slog.Warn("failed to insert audit log", "nodeID", node.ID, "Fingerprint", node.Fingerprint, "error", err)
}
}
Expand Down Expand Up @@ -393,7 +378,7 @@ func (m *manager) CullInactiveNodes(ctx context.Context, ttl time.Duration) erro

if m.config.EnabledAudit {
for _, lic := range releasedLicenses {
if err := m.store.InsertAuditLog(ctx, db.EventTypeNodeCulled, "license", lic.ID); err != nil {
if err := m.store.InsertAuditLog(ctx, db.EventTypeNodeCulled, db.EntityTypeLicense, lic.ID); err != nil {
slog.Error("failed to insert audit log", "licenseID", lic.ID, "error", err)
}
}
Expand Down

0 comments on commit 434acee

Please sign in to comment.