Skip to content

86232 - user-password-account-expiry - #273

Merged
MangirishK merged 27 commits into
mainfrom
usr/mangirish/IMPL-86232
Sep 10, 2026
Merged

MangirishK merged 27 commits into
mainfrom
usr/mangirish/IMPL-86232

Conversation

@MangirishK

Copy link
Copy Markdown
Contributor

Description

user-password-account-expiry

GitHub Issues

List the GitHub issues impacted by this PR:

GitHub Issue #

Checklist:

  • I have performed a self-review of my own code to ensure there are no formatting, pep8, linting, or security issues
  • I have performed Ansible Sanity test using --docker default
  • I have verified that new and existing unit tests pass locally with my changes
  • I have not allowed coverage numbers to degenerate
  • I have maintained at least 90% code coverage
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • Backward compatibility is not broken

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Please also list any relevant details for your test configuration

  • Test A
  • Test B

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.15571% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.95%. Comparing base (94d2e47) to head (4328390).

Files with missing lines Patch % Lines
plugins/modules/user.py 86.51% 6 Missing and 6 partials ⚠️
tests/unit/plugins/module_utils/mock_user_api.py 88.88% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #273      +/-   ##
==========================================
+ Coverage   90.90%   90.95%   +0.05%     
==========================================
  Files         192      192              
  Lines       26023    26305     +282     
  Branches     3065     3101      +36     
==========================================
+ Hits        23656    23926     +270     
- Misses       1596     1602       +6     
- Partials      771      777       +6     
Flag Coverage Δ
units 90.95% <95.15%> (+0.05%) ⬆️

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

☔ View full report in Codecov by Harness.
📢 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.

MangirishK and others added 27 commits September 10, 2026 07:59
Adds password_expires and expiry keys to USER_COMMON_ARGS, a
get_user_details() helper for per-test expiry state, epoch constants,
and the FR-5.1/FR-5.2 validation error messages.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…triction

Red phase for FR-1/FR-5.1: argument-spec parity, parameter-specific
non-local provider error, and local-provider acceptance via the not-yet-
existing validate_local_only_params helper.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…idation

Red phase for FR-2/FR-5.1/FR-5.2: non-local provider rejection, range
boundaries 0..4294967295, non-integer rejection including bool, and
ordering (validation before any create API call).

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
password_expires as bool and expiry as int (Unix epoch). Ansible's
type coercion handles the common conversion cases; module-level
validation follows in the next tasks.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Adds validate_local_only_params(), which fails with a parameter-specific
message naming password_expires or expiry rather than the generic
check_provider_type() error. Invoked from perform_module_operation
before set_validate_params so no API call is issued first.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Adds validate_expiry(): rejects non-integers (including bool, an int
subclass) and enforces the inclusive PAPI range 0..4294967295. Past
timestamps are delegated to the PowerScale API per ER Q6.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Phase 1 of Story-86232-part1: password_expires/expiry argument spec,
local-only provider validation, and expiry type/range validation.

33 user tests passed (19 pre-existing + 14 new), 96% coverage,
1426 collection-wide tests passed with 0 regressions.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Phase 2 TDD Red: six tests covering create-with-new-params,
preserve-when-omitted, explicit-zero-clears, password_expires-toggle,
and identical-params-unchanged.

3 fail as expected (create forwarding, expiry change, password_expires
change). 3 pass vacuously (omitted params, identical params) and will
remain passing after implementation.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…tection

Phase 2 Green: forward password_expires and expiry to
AuthUserCreateParams and AuthUser, add change detection in
is_user_modified_sensitive(), and map both fields in
get_user_params_from_details().

All 39 user tests pass (19 pre-existing + 14 Phase 1 + 6 Phase 2).
Coverage: 96%. Collection-wide: 0 new regressions.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Phase 3 TDD Red: four tests covering check-mode-with-diff for
password_expires and expiry, no-changes check mode, and diff
output without check mode.

3 fail as expected (API called in check mode, no diff output).
1 passes vacuously (no changes).

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Phase 3 Green: set supports_check_mode=True, guard create/update/delete
API calls with self.module.check_mode, and compute before/after diff
for password_expires and expiry via _build_expiry_diff().

All 43 user tests pass (19 pre-existing + 14 Phase 1 + 6 Phase 2 +
4 Phase 3). Coverage: 95%. Collection-wide: 0 new regressions.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Phase 4: add DOCUMENTATION option stanzas for password_expires and
expiry, RETURN entries for expired/password_expired/password_expiry/
max_password_age, regression test pinning AC-011 output fields, and
changelog fragment.

All 44 user tests pass. Coverage: 95%. ansible-doc renders cleanly.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Adds full parameter descriptions including cluster policy behavior,
local-user-only restriction note, idempotency behavior, bool rejection
note for expiry, and epoch-conversion troubleshooting tip (NFR-4).

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ansible-doc renders correctly with expanded descriptions for both
password_expires and expiry parameters. 44 unit tests pass.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Four new EXAMPLES: security user with password_expires: true, service
account with password_expires: false, contractor with expiry set, and
check-mode + diff preview. Enriched RETURN descriptions for expired,
password_expired, password_expiry, and max_password_age.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
All 4 EXAMPLES entries added and RETURN descriptions finalized.
ansible-doc renders correctly. 44 unit tests pass.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Adds end-to-end tasks: create with password_expires, idempotency
re-run with assert, contractor with expiry, update expiry, check-mode
+ diff preview, debug output, non-local provider note, and cleanup.
All pre-existing tasks preserved unchanged.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Syntax-check passes. 44 unit tests pass. Example playbook extended
with 9 new tasks covering password_expires, expiry, check-mode, and
cleanup.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Four minor_changes entries: expanded DOCUMENTATION, new EXAMPLES,
enriched RETURN descriptions, and extended example playbook.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Unit tests pass under Python 3.11 and 3.12. ansible-doc renders
cleanly. YAML doc parsing validates all fields. runtime.yml confirmed.
Changelog fragment added.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…/expiry

Adds _validate_isi_sdk_compatibility() — a lazy hasattr() check that
verifies the installed isi_sdk AuthUser model exposes password_expires
and expiry before any create/update API call. Fails clearly with an
unsupported-version message when the SDK lacks the attributes.

5 new unit tests: 3 parametrized acceptance (9.13.x/9.14.x/9.15.x),
1 rejection (missing attributes), 1 skip-when-absent. TDD: red/green
verified. 49 total tests pass, 0 regressions.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…mentation

49 unit tests pass (5 new). TDD cycle verified: RED (1 failure),
GREEN (49/49). _validate_isi_sdk_compatibility() implemented with
lazy hasattr() gate.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…idation

49 unit tests pass under Python 3.11 and 3.12. Collection-wide: 0
regressions in test_user.py. Lab verification deferred to user
(requires live PowerScale 9.15.x cluster). Changelog fragment added.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ate tests

The 3 new compatibility-gate tests set utils.isi_sdk.AuthUser via a
raw attribute assignment, which is never restored since utils.isi_sdk
is a process-wide singleton mock. Switched to mocker.patch.object so
the mutation is automatically reverted at the end of each test,
preventing order-dependent pollution of later tests in the same
pytest process.

Verified via a canary test appended immediately after the compatibility
tests confirming utils.isi_sdk.AuthUser is restored to its default
permissive state. 49/49 tests still pass.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@MangirishK
MangirishK force-pushed the usr/mangirish/IMPL-86232 branch from 4328390 to 682a5b5 Compare September 10, 2026 12:00
@MangirishK
MangirishK merged commit e709f3f into main Sep 10, 2026
25 checks passed
@MangirishK
MangirishK deleted the usr/mangirish/IMPL-86232 branch September 10, 2026 12:49
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