Skip to content

[chores] Added support for user expiration reminders #608#615

Open
pandafy wants to merge 1 commit into
masterfrom
issues/608-celery-beat-schedule
Open

[chores] Added support for user expiration reminders #608#615
pandafy wants to merge 1 commit into
masterfrom
issues/608-celery-beat-schedule

Conversation

@pandafy
Copy link
Copy Markdown
Member

@pandafy pandafy commented May 14, 2026

Checklist

  • I have read the OpenWISP Contributing Guidelines.
  • I have manually tested the changes proposed in this pull request.
  • N/A I have written new test cases for new code and/or updated existing tests for changes to existing code.
  • I have updated the documentation.

Reference to Existing Issue

Closes #608

Description of Changes

  • Added celery beat schedule for expiration reminder emails
  • Added support for openwisp_users expiration tasks
  • Added configurable reminder email schedule variable

Blockers

- Added celery beat schedule for expiration reminder emails
- Added support for openwisp_users expiration tasks
- Added configurable reminder email schedule variable

Closes #608
@pandafy pandafy self-assigned this May 14, 2026
Comment thread defaults/main.yml
Comment on lines +19 to +21
# TODO: Remove before merging
- "openwisp-radius[openvpn_status] @ https://github.com/openwisp/openwisp-radius/tarball/issues/706-user-expiration"
- "openwisp-users @ https://github.com/openwisp/openwisp-users/tarball/issues/499-user-expiration"
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

TODO: Remove before merging!

Comment thread defaults/main.yml
- bpython
# TODO: Remove before merging
- "openwisp-radius[openvpn_status] @ https://github.com/openwisp/openwisp-radius/tarball/issues/706-user-expiration"
- "openwisp-users @ https://github.com/openwisp/openwisp-users/tarball/issues/499-user-expiration"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CRITICAL: TODO items must be resolved before merging. Temporary tarball dependencies should not be merged to master.

"max_retries": {{ openwisp2_celery_broker_max_tries }},
}

CELERY_TIMEZONE = TIME_ZONE
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: The CELERY_TIMEZONE = TIME_ZONE setting is added here, but TIME_ZONE is defined later in the file (around line 420). While Python handles this at runtime, for clarity consider placing this after TIME_ZONE is defined, or add a comment noting it's a Django setting that will be resolved at runtime.

"schedule": crontab(**{ {{ cron_password_expiration_email }} }),
},
{% endif %}
"deactivate_expired_users": {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CRITICAL: The deactivate_expired_users task has been moved from openwisp_radius (conditional on openwisp2_radius and openwisp2_radius_periodic_tasks) to openwisp_users (always enabled). This changes behavior for non-RADIUS installations. Ensure this is intentional and that openwisp_users.tasks.deactivate_expired_users exists in all supported openwisp-users versions.

"schedule": crontab(**{ {{ cron_deactivate_expired_users }} }),
"args": None,
},
"expiration_reminder_email": {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CRITICAL: The expiration_reminder_email task runs unconditionally. Ensure openwisp_users.tasks.expiration_reminder_email exists in all supported openwisp-users versions, or wrap this in a conditional check similar to password_expiration_email above.

@kilo-code-bot
Copy link
Copy Markdown

kilo-code-bot Bot commented May 14, 2026

Code Review Summary

Status: 4 Issues Found | Recommendation: Address CRITICAL issues before merge

Overview

Severity Count
CRITICAL 3
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

CRITICAL

File Line Issue
defaults/main.yml 21 TODO items with temporary tarball dependencies must be resolved before merging
templates/openwisp2/settings.py 256 Task moved from conditional (RADIUS-only) to unconditional - verify compatibility
templates/openwisp2/settings.py 261 New task runs unconditionally - ensure task exists in all supported versions

WARNING

File Line Issue
templates/openwisp2/settings.py 248 CELERY_TIMEZONE setting placement could be clearer relative to TIME_ZONE definition
Other Observations (not in diff)
  1. Behavior Change: The deactivate_expired_users task was previously conditional on openwisp2_radius and openwisp2_radius_periodic_tasks, but is now always enabled. This may affect non-RADIUS installations.

  2. Task Order: The reminder email (minute 3) now runs AFTER deactivation (minute 1), which reverses the previous logic where deactivation was at minute 5. This appears intentional - deactivation happens after reminders have been sent.

  3. Documentation Updated: The role-variables.rst documentation correctly reflects the new cron variables.

Files Reviewed (3 files)
  • defaults/main.yml - 1 critical issue (TODO/temporary dependencies)
  • docs/user/role-variables.rst - No issues (documentation updated correctly)
  • templates/openwisp2/settings.py - 2 critical, 1 warning (task placement and compatibility)

Issue Alignment Check: This PR implements the changes described in #608 - adding celery beat schedules for expiration reminders and user deactivation tasks.

Testing Recommendation: Since this PR modifies celery beat schedules and moves tasks between modules, ensure integration tests verify:

  1. The tasks execute correctly in both RADIUS and non-RADIUS installations
  2. No duplicate task registrations occur
  3. The reminder email task exists in the openwisp-users package

Reviewed by kimi-k2.5 · 147,463 tokens

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR updates the Ansible OpenWISP2 role to support user expiration feature improvements. It adds GitHub tarball dependencies for two feature branches, adjusts Celery cron schedules by adding a new cron_expiration_reminder_email task at minute 3 and moving cron_deactivate_expired_users to minute 1, updates the Django settings to include CELERY_TIMEZONE and consolidate user expiration task scheduling using crontab parameters, and removes the redundant radius-specific deactivate task in favor of the centralized openwisp-users task.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

  • docker-openwisp#587: Directly related—both PRs address Celery beat scheduling updates for user deactivation by consolidating tasks, removing the radius-specific periodic task, and integrating the openwisp-users task as the primary implementation.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change (user expiration reminders) and includes the issue reference.
Description check ✅ Passed The description covers main changes and issue reference, though manual testing checklist item is unchecked and test cases item marked N/A.
Linked Issues check ✅ Passed The PR fully addresses issue #608 requirements: updates Celery beat schedule, keeps cron_deactivate_expired_users variable unchanged, adds reminder email support, and updates documentation.
Out of Scope Changes check ✅ Passed All changes are within scope: Celery beat configuration updates, new reminder email schedule variable, documentation updates, and cron schedule adjustments align with issue #608 objectives.
Bug Fixes ✅ Passed This PR adds user expiration reminder support (chore), not a bug fix. The commit title is "[chores]" and PR objectives describe feature additions. The custom check is not applicable.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issues/608-celery-beat-schedule

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

@openwisp-companion
Copy link
Copy Markdown

The CI is failing due to transient infrastructure issues (not related to your code). I have restarted the failed jobs automatically (1/3).

Copy link
Copy Markdown

@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.

♻️ Duplicate comments (2)
templates/openwisp2/settings.py (1)

248-248: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix import-time name resolution bug for CELERY_TIMEZONE.

Line 248 references TIME_ZONE before it is assigned (Line 420), which can fail at settings import time.

Proposed fix
-CELERY_TIMEZONE = TIME_ZONE
+CELERY_TIMEZONE = "{{ openwisp2_time_zone }}"
#!/bin/bash
python - <<'PY'
from pathlib import Path

p = Path("templates/openwisp2/settings.py")
lines = p.read_text().splitlines()

celery_tz_line = next(i+1 for i, l in enumerate(lines) if l.strip().startswith("CELERY_TIMEZONE"))
time_zone_line = next(i+1 for i, l in enumerate(lines) if l.strip().startswith("TIME_ZONE ="))

print(f"CELERY_TIMEZONE line: {celery_tz_line}")
print(f"TIME_ZONE line: {time_zone_line}")
print("time_zone_defined_before_reference:", time_zone_line < celery_tz_line)
PY
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/openwisp2/settings.py` at line 248, CELERY_TIMEZONE is referencing
TIME_ZONE before it's assigned; update settings so TIME_ZONE is defined prior to
using it (move the CELERY_TIMEZONE assignment to after the TIME_ZONE = ... line)
or change CELERY_TIMEZONE to read TIME_ZONE safely (e.g. via
globals().get('TIME_ZONE', '<default>')) so CELERY_TIMEZONE and TIME_ZONE in
templates/openwisp2/settings.py are resolved at import time; edit the
CELERY_TIMEZONE assignment or its position and ensure the symbols
CELERY_TIMEZONE and TIME_ZONE are consistently ordered or accessed safely.
defaults/main.yml (1)

19-21: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Remove temporary branch tarball dependencies from defaults before merge.

Line 19 explicitly marks this as temporary, and Line 20-Line 21 pin default installs to mutable GitHub issue branches, which is not safe/reproducible for master.

Proposed fix
 openwisp2_extra_python_packages:
   - bpython
-  # TODO: Remove before merging
-  - "openwisp-radius[openvpn_status] @ https://github.com/openwisp/openwisp-radius/tarball/issues/706-user-expiration"
-  - "openwisp-users @ https://github.com/openwisp/openwisp-users/tarball/issues/499-user-expiration"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@defaults/main.yml` around lines 19 - 21, Remove the temporary GitHub tarball
pins from defaults/main.yml: delete the entries containing
"openwisp-radius[openvpn_status] @
https://github.com/openwisp/openwisp-radius/tarball/issues/706-user-expiration"
and "openwisp-users @
https://github.com/openwisp/openwisp-users/tarball/issues/499-user-expiration"
and replace them with stable, reproducible pins (either the package name alone
or a released version spec, e.g., openwisp-radius==<released_version> and
openwisp-users==<released_version>) so defaults no longer reference mutable
issue-branch tarballs before merging.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@defaults/main.yml`:
- Around line 19-21: Remove the temporary GitHub tarball pins from
defaults/main.yml: delete the entries containing
"openwisp-radius[openvpn_status] @
https://github.com/openwisp/openwisp-radius/tarball/issues/706-user-expiration"
and "openwisp-users @
https://github.com/openwisp/openwisp-users/tarball/issues/499-user-expiration"
and replace them with stable, reproducible pins (either the package name alone
or a released version spec, e.g., openwisp-radius==<released_version> and
openwisp-users==<released_version>) so defaults no longer reference mutable
issue-branch tarballs before merging.

In `@templates/openwisp2/settings.py`:
- Line 248: CELERY_TIMEZONE is referencing TIME_ZONE before it's assigned;
update settings so TIME_ZONE is defined prior to using it (move the
CELERY_TIMEZONE assignment to after the TIME_ZONE = ... line) or change
CELERY_TIMEZONE to read TIME_ZONE safely (e.g. via globals().get('TIME_ZONE',
'<default>')) so CELERY_TIMEZONE and TIME_ZONE in
templates/openwisp2/settings.py are resolved at import time; edit the
CELERY_TIMEZONE assignment or its position and ensure the symbols
CELERY_TIMEZONE and TIME_ZONE are consistently ordered or accessed safely.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0fb0316e-f344-4d78-bbfd-81729ba4734b

📥 Commits

Reviewing files that changed from the base of the PR and between 817a4a0 and f3e0020.

📒 Files selected for processing (3)
  • defaults/main.yml
  • docs/user/role-variables.rst
  • templates/openwisp2/settings.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build debian12
  • GitHub Check: Build debian13
  • GitHub Check: Build ubuntu2404
  • GitHub Check: Build ubuntu2204
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{md,rst,txt}

📄 CodeRabbit inference engine (Custom checks)

**/*.{md,rst,txt}: Changes: If the change affects behavior that is already documented, the documentation must be updated to reflect the new behavior
Features: Documentation must mention the new feature; for heavily UI-related features, a new section or page is appropriate

Files:

  • docs/user/role-variables.rst
**/*.py

📄 CodeRabbit inference engine (Custom checks)

General: For Django pull requests, ensure all user-facing strings are marked as translatable using the Django i18n framework

Files:

  • templates/openwisp2/settings.py
🔇 Additional comments (3)
defaults/main.yml (1)

217-218: LGTM!

docs/user/role-variables.rst (1)

450-451: LGTM!

templates/openwisp2/settings.py (1)

256-264: LGTM!

@openwisp-companion
Copy link
Copy Markdown

The CI is failing due to transient infrastructure issues (not related to your code). I have restarted the failed jobs automatically (2/3).

@openwisp-companion
Copy link
Copy Markdown

The CI is failing due to transient infrastructure issues (not related to your code). I have restarted the failed jobs automatically (3/3).

@openwisp-companion
Copy link
Copy Markdown

Molecule Destroy Failure

Hello @pandafy,
(Analysis for commit f3e0020)

The Molecule destroy scenario failed because the instances could not be deleted. This is likely a transient infrastructure issue. The CI has been restarted automatically. If the issue persists, please report it.

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.

[chore] Update celery beat schedule for user expiration logic

1 participant