Skip to content

RHINENG-26450: replace string inventory IDs with uuid.UUID#2217

Open
katarinazaprazna wants to merge 1 commit into
RedHatInsights:masterfrom
katarinazaprazna:update-inventory-id-types
Open

RHINENG-26450: replace string inventory IDs with uuid.UUID#2217
katarinazaprazna wants to merge 1 commit into
RedHatInsights:masterfrom
katarinazaprazna:update-inventory-id-types

Conversation

@katarinazaprazna
Copy link
Copy Markdown
Collaborator

@katarinazaprazna katarinazaprazna commented May 29, 2026

Summary

Replace string inventory IDs with uuid.UUID across the entire backend, starting from the listener entry point (Host model) through internal models, evaluator, manager controllers, and middleware (RBAC/Kessel)

Ticket: https://redhat.atlassian.net/browse/RHINENG-26450

Secure Coding Practices Checklist GitHub Link

Secure Coding Checklist

  • Input Validation
  • Output Encoding
  • Authentication and Password Management
  • Session Management
  • Access Control
  • Cryptographic Practices
  • Error Handling and Logging
  • Data Protection
  • Communication Security
  • System Configuration
  • Database Security
  • File Management
  • Memory Management
  • General Coding Practices

Summary by Sourcery

Switch inventory and system identifier handling from strings to uuid.UUID across models, message payloads, controllers, and background tasks.

Enhancements:

  • Update core data models and helpers to store inventory IDs as uuid.UUID instead of strings.
  • Adjust HTTP handlers, middleware, and query builders to accept, validate, and query UUID-typed inventory IDs directly.
  • Align Kafka/mqueue platform events, notifications, and remediations payloads to carry UUID inventory IDs consistently.
  • Refactor RBAC, workspace/group parsing, and template/system advisory views to operate on UUID IDs while preserving existing response formats via string conversion.
  • Update listener, evaluator, and task logic (uploads, deletes, culling, repo-based sync) to work with UUID IDs and remove ::uuid casting from SQL where possible.
  • Adapt tests and test utilities throughout the codebase to the new UUID-based inventory ID types.

Summary by Sourcery

Switch inventory/system identifiers across backend services from strings to uuid.UUID, updating models, queries, handlers, and tests while preserving external string-based representations where required.

Enhancements:

  • Store inventory IDs as uuid.UUID in core data models and propagate the type change through evaluators, listeners, controllers, notification/remediation payloads, and background tasks.
  • Simplify SQL by removing explicit ::uuid casts and using typed UUID parameters in queries and helper utilities.
  • Tighten validation and parsing of inventory IDs and workspace/group identifiers by using uuid.Parse and uuid.UUID-aware helpers.
  • Adjust test fixtures and expectations to work with UUID-typed IDs, including sorting, comparison, and serialization logic.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 29, 2026

Reviewer's Guide

Switches inventory and system identifiers from string to uuid.UUID across core models, queries, controllers, Kafka/mqueue events, evaluator logic, middleware, and tests, ensuring end-to-end UUID-typed handling while preserving external string representations at the API boundary where needed.

File-Level Changes

Change Details Files
Model and DB-layer inventory IDs now use uuid.UUID instead of string.
  • Change SystemInventory.InventoryID (and related getters) to uuid.UUID and adjust DeletedSystem, SystemPlatformV2, and other structs to match.
  • Update GORM queries and helpers (e.g., SystemAdvisoriesByInventoryID, CheckSystemJustEvaluated, Package/Template helpers) to accept uuid.UUID and remove ::uuid casts from SQL.
  • Adjust database utility and query parsing (AttrParser) to understand uuid.UUID types and arrays where necessary.
base/models/models.go
base/database/utils.go
base/database/testing.go
base/database/query.go
Evaluator, notifications, and remediations now operate on UUID inventory IDs.
  • Change Evaluate, evaluateInDatabase, tryGetSystem, loadSystemData, lazySaveAdvisories, and packagesFromUpdateList to take uuid.UUID inventory IDs.
  • Update mqueue.PayloadTrackerEvent.InventoryID, notification.Context.InventoryID, and RemediationsState.HostID to uuid.UUID and ensure Kafka message keys use String() when needed.
  • Update evaluator tests to construct uuid.UUID test IDs and pass them through PlatformEvent.SystemIDs and DB helpers.
evaluator/evaluate.go
evaluator/evaluate_advisories.go
evaluator/evaluate_packages.go
evaluator/notifications.go
evaluator/notifications_test.go
evaluator/remediations.go
evaluator/remediations_test.go
evaluator/evaluate_test.go
evaluator/evaluate_advisories_test.go
Kafka/mqueue platform events and task-level EvalData now carry uuid.UUID IDs.
  • Change PlatformEvent.ID and PlatformEvent.SystemIDs and EvalData.InventoryID to uuid.UUID and adjust accountInventories maps and batching logic accordingly.
  • Update mqueue parsing/tests and platform_event tests to marshal/unmarshal UUIDs correctly from JSON and to build Kafka messages with string keys.
  • Adapt tasks (vmaas_sync, system_culling) and manager.kafka InventoryIDs2EvalData to use uuid.UUID throughout evaluation flows.
base/mqueue/platform_event.go
base/mqueue/platform_event_test.go
base/mqueue/mqueue_test.go
tasks/vmaas_sync/repo_based_test.go
tasks/system_culling/system_culling.go
tasks/system_culling/system_culling_test.go
manager/kafka/kafka.go
manager/kafka/kafka_test.go
HTTP controllers now parse UUIDs from path/JSON and query DB with uuid.UUID types.
  • Update system detail, advisories, packages, and export handlers to uuid.Parse path params, pass uuid.UUID into queries, and drop manual IsValidUUID helpers and ::uuid casts.
  • Change systems/template systems/IDs views and advisory systems structures to hold uuid.UUID IDs in response models while still serializing as strings where necessary.
  • Adjust TemplateSystemsUpdateRequest and related flows (checkTemplateSystems, assignTemplateSystems, assignCandlepinEnvironment, checkInventoryIDs) to accept []uuid.UUID and to sort UUID slices using bytes.Compare.
manager/controllers/system_detail.go
manager/controllers/system_advisories.go
manager/controllers/system_advisories_export.go
manager/controllers/system_packages.go
manager/controllers/system_packages_export.go
manager/controllers/systems.go
manager/controllers/template_systems.go
manager/controllers/template_systems_update.go
manager/controllers/template_subscribed_systems_update.go
manager/controllers/systems_advisories_view.go
manager/controllers/advisory_systems.go
Listener upload/delete flow and Host model now use uuid.UUID inventory IDs end-to-end.
  • Change listener.Host.ID and HostEvent construction helpers to uuid.UUID and propagate through updateSystemPlatform, storeOrUpdateSysPlatform, and processUpload.
  • Replace string-typed inventory IDs in listener tests and common helpers with uuid.UUID variables and update DB queries to drop ::uuid casts.
  • Ensure delete events (HandleDelete, createTestDeleteEvent) use uuid.UUID and DeletedSystem.InventoryID becomes uuid.UUID with correct recency checks using uuid.Nil sentinel.
listener/upload.go
listener/events.go
listener/common_test.go
listener/upload_test.go
listener/events_test.go
listener/event_buffers.go
RBAC, Kessel middleware, and inventory group parsing now treat group IDs as UUIDs.
  • Change rbac.InventoryGroup.ID to *uuid.UUID and utils.ParseInventoryGroup to accept *uuid.UUID, updating callers in RBAC and Kessel middlewares.
  • Update processWorkspaces and findInventoryGroups to parse workspace/group ResourceId strings into uuid.UUID before building InventoryGroup JSON.
  • Adjust tests to expect UUID-based workspace/group representations.
base/rbac/rbac.go
base/utils/core.go
manager/middlewares/rbac.go
manager/middlewares/kessel.go
manager/middlewares/kessel_test.go
Tests and fixtures updated to use uuid.UUID in models, controllers, and views.
  • Introduce shared uuid.UUID test constants (e.g., testInventoryID*, testOrgID) and replace string literals in tests across listener, evaluator, manager controllers, turnpike, and tasks.
  • Update assertions to compare uuid.UUID structs instead of strings, using .String() where endpoints still expose string IDs.
  • Adjust sorting/comparison logic in tests that previously used string comparison to now compare UUIDs via String() or bytes.Compare.
listener/common_test.go
listener/upload_test.go
listener/events_test.go
evaluator/*.go
manager/controllers/*_test.go
turnpike/controllers/admin_test.go
tasks/*_test.go
base/inventory_views/inventory_views_test.go
manager/controllers/test_utils.go

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@katarinazaprazna katarinazaprazna changed the title RHINENG-26450: update inventory id types RHINENG-26450: replace string inventory IDs with uuid.UUID May 29, 2026
@katarinazaprazna katarinazaprazna force-pushed the update-inventory-id-types branch from 7a25fdd to 6ca7a66 Compare May 29, 2026 01:20
Comment thread base/models/models.go Outdated
Comment thread manager/controllers/template_systems_update.go Outdated
Comment thread base/mqueue/mqueue_test.go Outdated
Comment thread listener/events.go Outdated
Comment thread manager/controllers/advisory_systems.go Outdated
Comment thread manager/controllers/utils.go Outdated
Comment thread manager/controllers/utils.go Outdated
Comment thread tasks/system_culling/system_culling_test.go
@TenSt TenSt self-assigned this May 29, 2026
@katarinazaprazna katarinazaprazna force-pushed the update-inventory-id-types branch from fc52ece to 4964ee4 Compare May 29, 2026 12:19
Comment thread manager/controllers/template_systems_update.go
@katarinazaprazna katarinazaprazna force-pushed the update-inventory-id-types branch 2 times, most recently from 43f8366 to 03ab857 Compare May 29, 2026 12:35
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 29, 2026

Codecov Report

❌ Patch coverage is 68.96552% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.07%. Comparing base (743010c) to head (de8eec6).

Files with missing lines Patch % Lines
base/database/testing.go 0.00% 9 Missing ⚠️
base/database/query.go 0.00% 6 Missing ⚠️
manager/controllers/system_detail.go 50.00% 5 Missing ⚠️
base/models/models.go 0.00% 4 Missing ⚠️
manager/controllers/systems_advisories_view.go 33.33% 0 Missing and 2 partials ⚠️
manager/controllers/template_systems_update.go 87.50% 0 Missing and 2 partials ⚠️
manager/controllers/utils.go 50.00% 2 Missing ⚠️
manager/middlewares/kessel.go 50.00% 1 Missing and 1 partial ⚠️
base/database/utils.go 0.00% 1 Missing ⚠️
base/utils/core.go 0.00% 1 Missing ⚠️
... and 2 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2217      +/-   ##
==========================================
+ Coverage   59.00%   59.07%   +0.06%     
==========================================
  Files         137      137              
  Lines        8831     8821      -10     
==========================================
  Hits         5211     5211              
+ Misses       3072     3064       -8     
+ Partials      548      546       -2     
Flag Coverage Δ
unittests 59.07% <68.96%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@katarinazaprazna katarinazaprazna marked this pull request as ready for review May 29, 2026 14:30
@katarinazaprazna katarinazaprazna requested a review from a team as a code owner May 29, 2026 14:30
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • In getSubscribedSystem, the DB result is read into a string and then passed to uuid.Parse with the error intentionally ignored; if the DB ever contains an invalid UUID this will be silently treated as “not found” — consider checking and logging the parse error (and returning a 500) to avoid masking data corruption or unexpected values.
  • Several places sort slices of UUIDs using bytes.Compare(x[i][:], x[j][:]) (e.g. in checkInventoryIDs); it may be clearer and less error-prone to centralize this into a small helper (e.g. lessUUID(a, b uuid.UUID) bool) or use uuid.UUID.String() for comparison to keep the sorting logic consistent and self-documenting.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `getSubscribedSystem`, the DB result is read into a string and then passed to `uuid.Parse` with the error intentionally ignored; if the DB ever contains an invalid UUID this will be silently treated as “not found” — consider checking and logging the parse error (and returning a 500) to avoid masking data corruption or unexpected values.
- Several places sort slices of UUIDs using `bytes.Compare(x[i][:], x[j][:])` (e.g. in `checkInventoryIDs`); it may be clearer and less error-prone to centralize this into a small helper (e.g. `lessUUID(a, b uuid.UUID) bool`) or use `uuid.UUID.String()` for comparison to keep the sorting logic consistent and self-documenting.

## Individual Comments

### Comment 1
<location path="manager/controllers/template_subscribed_systems_update.go" line_range="82-83" />
<code_context>
+		return 0, "", uuid.Nil, err
 	}
-	if inventoryID == "" {
+	inventoryID, _ := uuid.Parse(inventoryIDStr)
+	if inventoryID == uuid.Nil {
 		err := errors.Errorf("System %s not found", systemCn)
 		utils.LogAndRespNotFound(c, err, err.Error())
</code_context>
<issue_to_address>
**issue:** Consider handling uuid.Parse errors explicitly instead of ignoring them

`uuid.Parse(inventoryIDStr)` errors are ignored and only `uuid.Nil` is checked. If `inventory_id` is malformed, this will incorrectly become a 404 and lose the parse error context. Please handle the parse error explicitly (e.g., log and return a 500) so corrupted `system_inventory.inventory_id` values are distinguishable from a genuinely missing system.
</issue_to_address>

### Comment 2
<location path="manager/middlewares/rbac.go" line_range="176-180" />
<code_context>
 					continue
 				}
-				group, err := utils.ParseInventoryGroup(v, nil)
+				id, err := uuid.Parse(*v)
+				if err != nil {
+					continue
+				}
+				group, err := utils.ParseInventoryGroup(&id, nil)
 				if err != nil {
-					// couldn't marshal inventory group to json
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Skipping non-UUID inventory groups silently may hide misconfigured RBAC attributes

With this change, any `inventory_group.id` that fails `uuid.Parse` is now dropped silently, whereas previously non-UUID IDs were still passed to `ParseInventoryGroup`. If upstream RBAC data ever includes non-UUID IDs (e.g., due to misconfig), those groups will disappear with no signal. Please add at least debug/warn logging on parse failures so these issues are detectable.

Suggested implementation:

```golang
				id, err := uuid.Parse(*v)
				if err != nil {
					// log invalid inventory_group.id so RBAC misconfigurations are visible
					log.WithError(err).
						WithField("inventory_group_id", *v).
						Warn("skipping inventory group with invalid UUID in RBAC access")
					continue
				}
				group, err := utils.ParseInventoryGroup(&id, nil)

```

1. Ensure that `log` is a valid logger in this package:
   - If the project uses `logrus`, confirm that `log` is the configured `*logrus.Entry` (or adjust the call to match your logger, e.g. `logging.Log` or `logger`).
   - If no logger is available yet in this file, add an appropriate logger import (e.g. `github.com/sirupsen/logrus`) and initialize or use the project-standard logging facade.
2. Optionally, if your logging guidelines prefer debug over warn for this case, change `.Warn(...)` to `.Debug(...)` or use the appropriate level/method.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +82 to +83
inventoryID, _ := uuid.Parse(inventoryIDStr)
if inventoryID == uuid.Nil {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Consider handling uuid.Parse errors explicitly instead of ignoring them

uuid.Parse(inventoryIDStr) errors are ignored and only uuid.Nil is checked. If inventory_id is malformed, this will incorrectly become a 404 and lose the parse error context. Please handle the parse error explicitly (e.g., log and return a 500) so corrupted system_inventory.inventory_id values are distinguishable from a genuinely missing system.

Comment on lines +176 to +180
id, err := uuid.Parse(*v)
if err != nil {
continue
}
group, err := utils.ParseInventoryGroup(&id, nil)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Skipping non-UUID inventory groups silently may hide misconfigured RBAC attributes

With this change, any inventory_group.id that fails uuid.Parse is now dropped silently, whereas previously non-UUID IDs were still passed to ParseInventoryGroup. If upstream RBAC data ever includes non-UUID IDs (e.g., due to misconfig), those groups will disappear with no signal. Please add at least debug/warn logging on parse failures so these issues are detectable.

Suggested implementation:

				id, err := uuid.Parse(*v)
				if err != nil {
					// log invalid inventory_group.id so RBAC misconfigurations are visible
					log.WithError(err).
						WithField("inventory_group_id", *v).
						Warn("skipping inventory group with invalid UUID in RBAC access")
					continue
				}
				group, err := utils.ParseInventoryGroup(&id, nil)
  1. Ensure that log is a valid logger in this package:
    • If the project uses logrus, confirm that log is the configured *logrus.Entry (or adjust the call to match your logger, e.g. logging.Log or logger).
    • If no logger is available yet in this file, add an appropriate logger import (e.g. github.com/sirupsen/logrus) and initialize or use the project-standard logging facade.
  2. Optionally, if your logging guidelines prefer debug over warn for this case, change .Warn(...) to .Debug(...) or use the appropriate level/method.

@katarinazaprazna katarinazaprazna force-pushed the update-inventory-id-types branch from 03ab857 to de8eec6 Compare June 1, 2026 08:59
Copy link
Copy Markdown
Collaborator

@TenSt TenSt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants