feat: backfill RBAC role assignments for gap-window domains - #1445
Conversation
Reviewer's GuideIntroduces migration 0021 to backfill missing DomainOrg UserRole and GroupRole assignments by reusing the idempotent 0019 conversion, while disabling permission replacement to preserve current service-role permissions. The migration is independently deployable and intentionally irreversible via a no-op reverse. Sequence diagram for the DomainOrg RBAC backfill migrationsequenceDiagram
participant Migration0021
participant Migration0019
participant DomainOrg
participant Role
participant UserRole
participant GroupRole
participant ServiceRolePermissions
Migration0021->>Migration0019: convert_domainorgs_to_roles(apps, schema_editor, set_permissions=False)
Migration0019->>Role: _ensure_service_roles(apps, set_permissions=False)
Role-->>Migration0019: get_or_create service roles
Migration0019->>DomainOrg: read every DomainOrg row
loop each DomainOrg
Migration0019->>UserRole: get_or_create missing assignments
Migration0019->>GroupRole: get_or_create missing assignments
end
Migration0019-->>Migration0021: backfill complete
Migration0021-->>ServiceRolePermissions: permissions.set not called
Migration0021-->>Migration0021: reverse is noop
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="pulp_service/pulp_service/app/migrations/0021_backfill_domainorg_roles.py" line_range="25" />
<code_context>
+
+ operations = [
+ migrations.RunPython(
+ _migration_0019.convert_domainorgs_to_roles,
+ migrations.RunPython.noop,
+ ),
</code_context>
<issue_to_address>
**issue (broader_impact):** The backfill invokes 0019's entire conversion function, which calls `_ensure_service_roles` and executes `permissions.set(...)` for `service.domain_admin` and `service.domain_viewer`. This replaces the existing permission memberships, so a deployment can overwrite intentional role customizations or permission changes made since migration 0019; the operation is not limited to filling missing DomainOrg assignments as the surrounding comments claim.
**Triggers:** When the service roles have permission memberships that differ from the current set of plugin permissions.
**Suggested fix:** Extract or invoke only the DomainOrg role-assignment portion of the conversion, leaving service-role permission memberships and other one-time policy assignments untouched.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 1 finding to address first, and the migration persists RBAC role assignments, so an incorrect conversion could grant or remove access for affected domains and require manual database cleanup. Its reverse operation is a no-op, meaning reverting the code would not remove assignments already created.
Blocking findings: pulp_service/pulp_service/app/migrations/0021_backfill_domainorg_roles.py:25
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
c6f0b76 to
82ed9c6
Compare
|
@sourcery-ai review |
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="pulp_service/pulp_service/app/migrations/0021_backfill_domainorg_roles.py" line_range="24" />
<code_context>
+ # membership, so running it here would overwrite any service-role permission
+ # changes made since 0019. The post_migrate handler keeps those permissions
+ # authoritative; this backfill leaves them untouched.
+ _migration_0019.convert_domainorgs_to_roles(apps, schema_editor, set_permissions=False)
+
+
</code_context>
<issue_to_address>
**issue (broader_impact):** The backfill invokes the entire 0019 conversion, which also processes the current `DOMAIN_ACCESS_POLICIES` and creates readonly-group role assignments independently of `DomainOrg` rows. A policy added or changed after 0019 therefore grants new readonly roles to unrelated existing domains during 0021, despite the migration's stated scope being only missing DomainOrg assignments.
**Triggers:** When `DOMAIN_ACCESS_POLICIES` differs from the configuration used when migration 0019 ran.
**Suggested fix:** Extract or add a conversion helper that processes only DomainOrg assignments, and do not execute 0019's readonly-policy loop from the backfill.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 1 finding to address first, and this migration persists RBAC role assignments for existing domains, which can grant or withhold authorization. If the assignment logic is wrong, reverting the code does not remove those persisted access changes; they would require a separate corrective migration or manual cleanup.
Blocking findings: pulp_service/pulp_service/app/migrations/0021_backfill_domainorg_roles.py:24
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Add data migration 0021 that re-runs migration 0019's DomainOrg-to-roles conversion (PULP-1893) over every DomainOrg row. This backfills the finite, now-frozen set of domains created in the window between the initial 0019 migration and the PULP-2119 dual-write deploy -- rows that have domains but no UserRole/GroupRole assignments. The migration imports convert_domainorgs_to_roles from 0019 via importlib (the module name starts with a digit, so a normal import will not parse) and runs it with set_permissions=False. The conversion is idempotent (get_or_create throughout), so domains that already have their roles -- from 0019 or the 2119 dual-write -- are skipped and only gap domains are filled. set_permissions=False keeps the backfill limited to DomainOrg role assignments: it does not call permissions.set(...) on the service roles, so it cannot overwrite service-role permission membership changes made since 0019 (the post_migrate handler keeps those authoritative). Reverse is a no-op: a backfill cannot distinguish rows it created from pre-existing ones, and this keeps rollback isolated from the later PULP-2120 permission-class switch. Shipped as its own deploy, separate from PULP-2120, so the backfill can be validated independently and a bad backfill rolls back without reverting the high-risk permission switch-over. Signed-off-by: Bryan Ramos <bramos@redhat.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
82ed9c6 to
7b68602
Compare
Add migration 0021 to backfill RBAC role assignments (PULP-1893). Some domains were created between the 0019 migration and the PULP-2119 dual-write deploy but never got their UserRole/GroupRole assignments. This fills them in.
It re-runs 0019's convert_domainorgs_to_roles over every DomainOrg row. (0019's module name starts with a digit, so we load the function via
importlibinstead of a normal import.) The function is idempotent, so domains that already have roles are skipped and only the missing ones get filled.Reverse is a no-op: a backfill can't tell which rows it created, and this keeps rollback separate from the later PULP-2120 permission switch.
Shipped on its own, apart from PULP-2120, so the backfill can be tested alone and a bad one rolls back without touching the risky permission change.
Summary by Sourcery
Backfill RBAC assignments for domains missed between the original conversion migration and dual-write deployment while preserving existing role permissions and keeping rollback non-destructive.
Bug Fixes:
Enhancements: