Skip to content

[AAP-72504] Add configurable page_size and jwt_expiration for resource sync#991

Open
huffmanca wants to merge 1 commit intoansible:develfrom
huffmanca:AAP-72504
Open

[AAP-72504] Add configurable page_size and jwt_expiration for resource sync#991
huffmanca wants to merge 1 commit intoansible:develfrom
huffmanca:AAP-72504

Conversation

@huffmanca
Copy link
Copy Markdown
Contributor

@huffmanca huffmanca commented Apr 30, 2026

Description

Allow operators to tune RESOURCE_SYNC_PAGE_SIZE and RESOURCE_SYNC_JWT_EXPIRATION via Django settings. These are read automatically by SyncExecutor and create_api_client(), so consuming services (tower, hub, EDA) pick up new values without code changes.

This change is occurring due to multiple customers having pagination issues, and also the performance impact of having a hardcoded page_size value of 50 when thousands of roles exist.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Test update
  • Refactoring (no functional changes)
  • Development environment change
  • Configuration change

Self-Review Checklist

  • I have performed a self-review of my code
  • I have added relevant comments to complex code sections
  • I have updated documentation where needed
  • I have considered the security impact of these changes
  • I have considered performance implications
  • I have thought about error handling and edge cases
  • I have tested the changes in my local environment

Testing Instructions

Prerequisites

Steps to Test

Expected Results

Additional Context

Required Actions

  • Requires documentation updates
  • Requires downstream repository changes
  • Requires infrastructure/deployment changes
  • Requires coordination with other teams
  • Blocked by PR/MR: #XXX

Screenshots/Logs

Summary by CodeRabbit

  • New Features

    • Resource sync command now supports an optional --page-size parameter to control pagination when fetching assignments.
    • Added configurable settings for resource synchronization: RESOURCE_SYNC_JWT_EXPIRATION and RESOURCE_SYNC_PAGE_SIZE with sensible defaults.
  • Tests

    • Added test coverage for pagination and settings-driven configuration in resource sync operations.

…e sync

Allow operators to tune RESOURCE_SYNC_PAGE_SIZE and
RESOURCE_SYNC_JWT_EXPIRATION via Django settings. These are read
automatically by SyncExecutor and create_api_client(), so consuming
services (tower, hub, EDA) pick up new values without code changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

DVCS PR Check Results:

PR appears valid (JIRA key(s) found)

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

📝 Walkthrough

Walkthrough

The changes add configurable pagination and JWT expiration to the resource synchronization layer. New settings keys control page size (default 50) and JWT expiration (default 60), exposed via command-line parameter and threaded through the sync executor to the remote assignment fetcher.

Changes

Cohort / File(s) Summary
Configuration Defaults
ansible_base/lib/dynamic_config/settings_logic.py
Added two new default config keys to resource_registry_defaults: RESOURCE_SYNC_PAGE_SIZE (50) and RESOURCE_SYNC_JWT_EXPIRATION (60) applied only when not already present in incoming settings.
Command-Line Interface
ansible_base/resource_registry/management/commands/resource_sync.py
Introduced optional --page-size parameter with validation ensuring value ≥ 1; parameter forwarded to SyncExecutor via options filtering allowlist.
Sync Core Logic
ansible_base/resource_registry/tasks/sync.py
Updated function signatures: get_remote_assignments() and RemoteAssignmentFetcher.__init__() now accept optional page_size parameter (defaults to settings value). SyncExecutor adds page_size field and passes it to remote assignment fetcher. JWT expiration injected into API client creation.
Test Coverage
test_app/tests/resource_registry/test_resource_sync.py
Added test assertions verifying page_size inclusion in pagination filters, SyncExecutor parameter forwarding, and create_api_client() reading RESOURCE_SYNC_JWT_EXPIRATION from Django settings.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: adding configurable page_size and jwt_expiration parameters for resource sync, matching the core objectives of this pull request.
Docstring Coverage ✅ Passed Docstring coverage is 87.50% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ansible_base/resource_registry/tasks/sync.py`:
- Around line 194-197: The constructor for the sync class currently accepts
page_size without validation (see __init__ and the page_size attribute) which
allows 0/negative/non-int values to silently enable partial-sync; update
__init__ to coerce and validate page_size: if page_size is not None attempt
int(page_size) and if conversion fails or the value is <= 0, fall back to a safe
default from getattr(settings, 'RESOURCE_SYNC_PAGE_SIZE', 50) (also validate
that setting as an int > 0 and fall back to 50 if not); assign the validated
positive int to self.page_size and ensure the same validation logic is applied
where page_size is read/used elsewhere (referenced around the other occurrence
noted) so pagination calls never receive non-positive or non-integer values.
- Line 112: Validate and sanitize settings.RESOURCE_SYNC_JWT_EXPIRATION before
assigning to params["jwt_expiration"]: ensure the value from settings is an
integer > 0 (coerce with int() safely), and if it's missing, non-numeric, or
non-positive, replace it with the default 60 (and optionally log/warn). Modify
the assignment around params["jwt_expiration"] in sync.py to perform this
check/coercion rather than forwarding the raw settings value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: b37132a0-ff60-4069-ab05-d2f971bf1cf3

📥 Commits

Reviewing files that changed from the base of the PR and between d4ea85e and 7d8581e.

📒 Files selected for processing (4)
  • ansible_base/lib/dynamic_config/settings_logic.py
  • ansible_base/resource_registry/management/commands/resource_sync.py
  • ansible_base/resource_registry/tasks/sync.py
  • test_app/tests/resource_registry/test_resource_sync.py

if not service_path:
raise ValueError("RESOURCE_SERVICE_PATH is not set.")
params["service_path"] = service_path
params["jwt_expiration"] = getattr(settings, "RESOURCE_SYNC_JWT_EXPIRATION", 60)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate RESOURCE_SYNC_JWT_EXPIRATION before passing it to the client.

Right now any setting value is forwarded as-is. Non-integer or non-positive values can cause token-generation/auth failures at runtime and break sync jobs.

Suggested fix
-    params["jwt_expiration"] = getattr(settings, "RESOURCE_SYNC_JWT_EXPIRATION", 60)
+    raw_jwt_expiration = getattr(settings, "RESOURCE_SYNC_JWT_EXPIRATION", 60)
+    try:
+        jwt_expiration = int(raw_jwt_expiration)
+    except (TypeError, ValueError) as exc:
+        raise ValueError("RESOURCE_SYNC_JWT_EXPIRATION must be an integer >= 1") from exc
+    if jwt_expiration < 1:
+        raise ValueError("RESOURCE_SYNC_JWT_EXPIRATION must be an integer >= 1")
+    params["jwt_expiration"] = jwt_expiration
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
params["jwt_expiration"] = getattr(settings, "RESOURCE_SYNC_JWT_EXPIRATION", 60)
raw_jwt_expiration = getattr(settings, "RESOURCE_SYNC_JWT_EXPIRATION", 60)
try:
jwt_expiration = int(raw_jwt_expiration)
except (TypeError, ValueError) as exc:
raise ValueError("RESOURCE_SYNC_JWT_EXPIRATION must be an integer >= 1") from exc
if jwt_expiration < 1:
raise ValueError("RESOURCE_SYNC_JWT_EXPIRATION must be an integer >= 1")
params["jwt_expiration"] = jwt_expiration
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ansible_base/resource_registry/tasks/sync.py` at line 112, Validate and
sanitize settings.RESOURCE_SYNC_JWT_EXPIRATION before assigning to
params["jwt_expiration"]: ensure the value from settings is an integer > 0
(coerce with int() safely), and if it's missing, non-numeric, or non-positive,
replace it with the default 60 (and optionally log/warn). Modify the assignment
around params["jwt_expiration"] in sync.py to perform this check/coercion rather
than forwarding the raw settings value.

Comment on lines +194 to +197
def __init__(self, api_client: ResourceAPIClient, page_size: int | None = None):
self.api_client = api_client
self.assignments: set[AssignmentTuple] = set()
self.page_size = page_size if page_size is not None else getattr(settings, 'RESOURCE_SYNC_PAGE_SIZE', 50)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Harden page-size parsing to prevent silent partial-sync mode.

RESOURCE_SYNC_PAGE_SIZE/page_size is used without validation. Invalid values (e.g., 0, negative, non-int) can make pagination calls fail; then assignment deletions are skipped due to incomplete fetch, causing persistent local/remote drift.

Suggested fix
     def __init__(self, api_client: ResourceAPIClient, page_size: int | None = None):
         self.api_client = api_client
         self.assignments: set[AssignmentTuple] = set()
-        self.page_size = page_size if page_size is not None else getattr(settings, 'RESOURCE_SYNC_PAGE_SIZE', 50)
+        raw_page_size = page_size if page_size is not None else getattr(settings, 'RESOURCE_SYNC_PAGE_SIZE', 50)
+        try:
+            resolved_page_size = int(raw_page_size)
+        except (TypeError, ValueError) as exc:
+            raise ValueError("RESOURCE_SYNC_PAGE_SIZE/page_size must be an integer >= 1") from exc
+        if resolved_page_size < 1:
+            raise ValueError("RESOURCE_SYNC_PAGE_SIZE/page_size must be an integer >= 1")
+        self.page_size = resolved_page_size

Also applies to: 224-224

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ansible_base/resource_registry/tasks/sync.py` around lines 194 - 197, The
constructor for the sync class currently accepts page_size without validation
(see __init__ and the page_size attribute) which allows 0/negative/non-int
values to silently enable partial-sync; update __init__ to coerce and validate
page_size: if page_size is not None attempt int(page_size) and if conversion
fails or the value is <= 0, fall back to a safe default from getattr(settings,
'RESOURCE_SYNC_PAGE_SIZE', 50) (also validate that setting as an int > 0 and
fall back to 50 if not); assign the validated positive int to self.page_size and
ensure the same validation logic is applied where page_size is read/used
elsewhere (referenced around the other occurrence noted) so pagination calls
never receive non-positive or non-integer values.

@sonarqubecloud
Copy link
Copy Markdown

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.

1 participant