Skip to content

fix(plugins): replace ansible.utils.ipaddr with stdlib-based test plugin#24

Merged
lexfrei merged 8 commits intomainfrom
fix/replace-ipaddr-with-stdlib
Apr 15, 2026
Merged

fix(plugins): replace ansible.utils.ipaddr with stdlib-based test plugin#24
lexfrei merged 8 commits intomainfrom
fix/replace-ipaddr-with-stdlib

Conversation

@lexfrei
Copy link
Copy Markdown
Contributor

@lexfrei lexfrei commented Apr 12, 2026

Problem

The role validated master node IPs with ansible.utils.ipaddr, which requires the netaddr Python package. ansible-galaxy collection install does not pull netaddr for users, and the README never documented the requirement — so users following the docs hit a cryptic runtime failure at the validation task.

Solution

Replace the single ipaddr usage with a bundled Jinja2 test plugin backed by Python's standard library ipaddress module. The new plugin has no external dependencies, supports both IPv4 and IPv6, and enforces the documented type: str contract (rejecting int/bool/bytes).

Changes

Plugin

  • Add plugins/test/ip_address.pyis_ip_address test using stdlib
  • Switch compute-master-nodes.yml to cozystack.installer.is_ip_address

Dependencies

  • Drop ansible.utils from galaxy.yml and requirements.yml
  • Drop netaddr pip install and ansible.utils install from CI

Tests

  • Unit tests at tests/unit/plugins/test/test_ip_address.py covering IPv4, IPv6, hostnames, malformed strings, None, int/bool/bytes rejection, and CIDR rejection
  • Wire ansible-test units into the sanity CI job
  • Add tests/test-ipv6-inventory.yml with documentation-range IPv6 addresses; new CI step verifies IPv6 host keys are accepted

Versioning & docs

  • Bump galaxy.yml to 1.2.3, add version_added to plugin DOCUMENTATION
  • Update examples/*/requirements.yml to v1.2.3 (with v prefix matching git tags)
  • Backfill CHANGELOG for v1.1.3, v1.2.1, v1.2.2 and add v1.2.3 entry
  • Fix stale cozystack_chart_version default in README (1.1.2 → 1.2.2)

Closes #18

Summary by CodeRabbit

  • New Features

    • Added IPv6 host key support with dedicated test inventory fixture.
    • Introduced built-in IP address validation test.
  • Chores

    • Removed ansible.utils collection dependency.
    • Updated version to v1.2.3 and default chart version to 1.2.2.
  • Tests

    • Added unit tests for IP address validation covering IPv4, IPv6, and edge cases.

lexfrei added 6 commits April 12, 2026 20:44
The role used ansible.utils.ipaddr to validate master node IPs, which
requires the netaddr Python package. netaddr is not installed by
ansible-galaxy collection install and was not documented as a prerequisite,
causing runtime failures for users who followed the README.

Replace the single ipaddr usage with a new test plugin that uses the
Python standard library ipaddress module. The plugin has no external
dependencies and supports both IPv4 and IPv6.

- Add plugins/test/ip_address.py with is_ip_address test
- Use cozystack.installer.is_ip_address in compute-master-nodes.yml
- Drop ansible.utils collection dependency (galaxy.yml, requirements.yml)
- Drop netaddr pip install and ansible.utils install from CI
- Add IPv6 inventory fixture and CI step to verify IPv6 acceptance

Closes #18

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
…Pv6 fix

- Replace fe80::1 with 2001:db8::12 in IPv6 test inventory:
  link-local addresses without scope ID are not realistic cluster
  IPs and make the test misleading.
- Add unit tests for plugins/test/ip_address.py with ansible-test
  units coverage for IPv4, IPv6, hostnames, malformed strings, and
  None input.
- Add CI step to run ansible-test units.
- Add version_added to plugin DOCUMENTATION.
- Document the dependency drop and new test in CHANGELOG.rst.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
- is_ip_address now rejects non-string inputs. ipaddress.ip_address()
  silently accepts int/bool (treating them as 32-bit address values),
  violating the documented type: str contract.
- Bump collection version to 1.2.3 to match CHANGELOG entry and
  plugin version_added so ansible-test sanity passes.
- Unit tests cover int, bool, bytes, and list rejection.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
- Update examples/*/requirements.yml from 1.2.2 to v1.2.3. Also
  adopts the v prefix — git tags are v-prefixed and installs via
  type: git fail without it.
- Fill in missing CHANGELOG entries for v1.1.3, v1.2.1 and v1.2.2
  so the v1.2.3 entry does not appear to jump from v1.1.2.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
- Add empty __init__.py to tests/unit/, tests/unit/plugins/ and
  tests/unit/plugins/test/. ansible-test units (ansible-core >= 2.15)
  requires these for pytest to resolve the FQCN import of the plugin
  module, otherwise the new Run unit tests CI step would fail with a
  collection import error.
- Fix stale cozystack_chart_version default in README (1.1.2 to 1.2.2).
  The actual default in roles/cozystack/defaults/main.yml is 1.2.2.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
ipaddress.ip_address() rejects CIDR notation since CIDR represents
a network rather than a single address. Add explicit test cases to
document this for both IPv4 and IPv6 CIDR inputs.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
@lexfrei lexfrei marked this pull request as ready for review April 12, 2026 18:22
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 12, 2026

Warning

Rate limit exceeded

@lexfrei has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 51 minutes and 8 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 51 minutes and 8 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f8a55e0f-814e-4ae8-bbf7-0a87f2540824

📥 Commits

Reviewing files that changed from the base of the PR and between 9e07947 and c38423a.

📒 Files selected for processing (2)
  • .github/workflows/test.yml
  • CHANGELOG.rst
📝 Walkthrough

Walkthrough

This PR removes the ansible.utils collection dependency and netaddr Python requirement by implementing a custom Ansible test plugin (is_ip_address) using Python's standard ipaddress library. The collection version is bumped to 1.2.3, and IPv6 testing coverage is added via new inventory fixtures and CI workflow updates.

Changes

Cohort / File(s) Summary
Collection Versioning & Dependencies
galaxy.yml, requirements.yml, examples/rhel/requirements.yml, examples/suse/requirements.yml, examples/ubuntu/requirements.yml, README.md
Updated collection/chart versions: 1.2.2 → 1.2.3 (or v1.2.3 in examples). Removed ansible.utils dependency from galaxy.yml and requirements.yml.
Custom IP Address Validation Plugin
plugins/test/ip_address.py, roles/cozystack/tasks/compute-master-nodes.yml
Added new is_ip_address Jinja2 test plugin validating IPv4/IPv6 using Python's ipaddress library. Replaced ansible.utils.ipaddr filter with custom test in compute-master-nodes validation task.
Plugin Unit Tests & IPv6 Fixtures
tests/unit/plugins/test/test_ip_address.py, tests/test-ipv6-inventory.yml
Added comprehensive unit tests for is_ip_address covering IPv4, IPv6, CIDR rejection, and non-string inputs. Added IPv6 inventory fixture with literal IPv6 host keys for testing IPv6 host key acceptance.
CI/CD Workflow Updates
.github/workflows/test.yml
Added ansible-test units --python 3.14 step, updated master-nodes job to build/install collection artifact, added IPv6 playbook validation run, removed netaddr from e2e job dependencies.
Release Documentation
CHANGELOG.rst
Added release notes for v1.2.3, v1.2.2, v1.2.1, v1.1.3 documenting dependency removal, custom IP validation, IPv6 support, and related fixes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • Issue #17: Related to examples version tag format standardization (updating examples to use v1.2.3 git tag prefix pattern).

Poem

🐰 No netaddr, no fuss at all,
A custom test to heed the call,
IPv6 hops now hop with ease,
Standard library puts minds at peace! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: replacing ansible.utils.ipaddr (a filter) with a stdlib-based test plugin, which is the core of this PR.
Description check ✅ Passed The description is comprehensive and well-structured, covering problem, solution, and detailed changes across plugins, dependencies, tests, and versioning.
Linked Issues check ✅ Passed The PR fully addresses issue #18 by replacing ansible.utils.ipaddr with a stdlib ipaddress-based test plugin, eliminating the netaddr dependency and enabling out-of-the-box functionality.
Out of Scope Changes check ✅ Passed All changes are scoped to resolving the netaddr dependency issue: plugin implementation, dependency removal, CI updates, tests, and version/docs updates are all directly related to the core objective.

✏️ 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 fix/replace-ipaddr-with-stdlib

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

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

@lexfrei lexfrei enabled auto-merge (squash) April 12, 2026 18:22
@lexfrei lexfrei self-assigned this Apr 12, 2026
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
roles/cozystack/tasks/compute-master-nodes.yml (1)

24-29: ⚠️ Potential issue | 🟡 Minor

Trim split values before validation to avoid false negatives.

Comma-separated values with spaces (for example, "10.0.0.1, 10.0.0.2") will currently fail for the second item even when the IP itself is valid.

Suggested fix
-  loop: "{{ _cozystack_master_nodes.split(',') }}"
+  loop: "{{ _cozystack_master_nodes.split(',') | map('trim') | list }}"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@roles/cozystack/tasks/compute-master-nodes.yml` around lines 24 - 29, The
loop is splitting _cozystack_master_nodes by commas but not trimming whitespace,
causing valid IPs like " 10.0.0.2" to fail the is_ip_address test; update the
loop to trim each split value before validation (e.g., apply a trim/map to the
split results or trim each item before running the is_ip_address check) so the
task that references _cozystack_master_nodes and the is_ip_address test
validates the cleaned values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@roles/cozystack/tasks/compute-master-nodes.yml`:
- Around line 24-29: The loop is splitting _cozystack_master_nodes by commas but
not trimming whitespace, causing valid IPs like " 10.0.0.2" to fail the
is_ip_address test; update the loop to trim each split value before validation
(e.g., apply a trim/map to the split results or trim each item before running
the is_ip_address check) so the task that references _cozystack_master_nodes and
the is_ip_address test validates the cleaned values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 37fd95f7-73a4-4d99-8af4-18e737411e99

📥 Commits

Reviewing files that changed from the base of the PR and between 07f63dd and 9e07947.

📒 Files selected for processing (15)
  • .github/workflows/test.yml
  • CHANGELOG.rst
  • README.md
  • examples/rhel/requirements.yml
  • examples/suse/requirements.yml
  • examples/ubuntu/requirements.yml
  • galaxy.yml
  • plugins/test/ip_address.py
  • requirements.yml
  • roles/cozystack/tasks/compute-master-nodes.yml
  • tests/test-ipv6-inventory.yml
  • tests/unit/__init__.py
  • tests/unit/plugins/__init__.py
  • tests/unit/plugins/test/__init__.py
  • tests/unit/plugins/test/test_ip_address.py
💤 Files with no reviewable changes (1)
  • requirements.yml

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the cozystack.installer to version 1.2.3, removing dependencies on ansible.utils and netaddr by introducing a bundled is_ip_address Jinja2 test. The changes include IPv6 support for inventory host keys, updated example requirements, and new unit tests for the IP validation plugin. A formatting correction is required in the CHANGELOG.rst to ensure the title underline length matches the text length for valid reStructuredText.

Comment thread CHANGELOG.rst Outdated
@@ -2,6 +2,39 @@
cozystack.installer Release Notes
============================
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The underline for the main title is too short. In reStructuredText (RST), the underline (and overline, if present) must be at least as long as the title text to be valid. The title 'cozystack.installer Release Notes' is 33 characters long, but the underline is only 28 characters.

Suggested change
============================
=================================

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed. The title is 33 chars; both the overline and underline are now 33 = characters to satisfy the RST requirement.

lexfrei added 2 commits April 13, 2026 23:02
The title 'cozystack.installer Release Notes' is 33 characters, but
the overline and underline were only 28. RST requires them to be at
least as long as the title, so tooling that parses the file strictly
would reject it.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
ansible-test units runs pytest against the controller interpreter and
expects pytest (plus the -n auto helpers pytest-xdist/pytest-forked
and the commonly-used pytest-mock) to be importable there. Without
these the job fails with 'No module named pytest' before any test
runs.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Copy link
Copy Markdown

@kitsunoff kitsunoff left a comment

Choose a reason for hiding this comment

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

LGTM. Clean dependency removal — stdlib ipaddress is the right call for a single validation use case. Plugin enforces the type: str contract explicitly, unit test coverage is thorough, and CI no longer needs netaddr. Backfilled CHANGELOG entries are a nice touch.

@lexfrei lexfrei merged commit 36c628b into main Apr 15, 2026
6 checks passed
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.

netaddr is missing in collection

2 participants