Skip to content

AAP-68210 Use FQCN throughout collection, and reduce dynamic templating in favor of release-based#16347

Open
AlanCoding wants to merge 6 commits intoansible:develfrom
AlanCoding:collection_fqcn
Open

AAP-68210 Use FQCN throughout collection, and reduce dynamic templating in favor of release-based#16347
AlanCoding wants to merge 6 commits intoansible:develfrom
AlanCoding:collection_fqcn

Conversation

@AlanCoding
Copy link
Member

@AlanCoding AlanCoding commented Mar 10, 2026

SUMMARY

Replacement for #16343

This puts FQCN everywhere like awx.awx.host, and allows a what-you-see-is-what-you-get.

As a tradeoff, this introduces a downstream-ify script that must be ran for every major release branch to transform into the ansible.controller collection, or else things will break.

ISSUE TYPE
  • New or Enhanced Feature
COMPONENT NAME
  • API

Note

Medium Risk
Touches broad collection-facing surfaces (docs/examples, build/release automation, CI, and API URL construction), so a missed conversion or prefix change could break downstream releases or CI/integration tests.

Overview
Makes the collection “what you see is what you get” by standardizing on explicit FQCNs and shifting downstream renames to a release-branch conversion step. Module/lookup docs and examples are updated to use awx.awx.* everywhere, while ControllerAPIModule now derives collection type from a canonical _COLLECTION_FQCN and controller_meta reports the full FQCN.

Build/release plumbing is simplified: Makefile reads namespace/name from awx_collection/galaxy.yml, the template_galaxy role now only stamps versions (no more dynamic FQCN/README/galaxy templating), and a new awx_collection/tools/replace_fqcn.sh converts the source tree to ansible.controller for downstream release branches (with CI checks to ensure conversion happened).

CI/promote workflows are updated to parameterize collection namespace/name, adjust artifact paths accordingly, and force /api/ routing for tests via a new api_prefix option plus CONTROLLER_OPTIONAL_API_URLPATTERN_PREFIX usage (also applied in awx-operator molecule runs and collection integration tests).

Written by Cursor Bugbot for commit b235b84. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added API prefix configuration support for customizing API URL paths in controller connections.
  • Documentation

    • Updated all module examples to use fully-qualified collection names for clarity.
    • Enhanced collection README with improved configuration examples and updated references.
    • Clarified collection namespace and package handling for better multi-platform support.

@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

📝 Walkthrough

Walkthrough

This change introduces a flexible collection identity system that allows the AWX collection to be distributed with different FQCNs depending on the repository. It establishes environment variables for namespace and package, implements dynamic FQCN derivation in core utilities, updates module documentation to use fully-qualified names, and adds infrastructure for converting FQCN references during release branches.

Changes

Cohort / File(s) Summary
CI/CD Workflows
.github/workflows/ci.yml, .github/workflows/promote.yml
Added environment variables (COLLECTION_NAMESPACE, COLLECTION_PACKAGE) to distinguish between ansible/controller and awx/awx based on repository. Integrated conditional FQCN conversion steps and API prefix parameter propagation. Replaced hardcoded collection paths with dynamic references.
Build Configuration
Makefile, awx_collection/tools/template_galaxy.yml
Changed COLLECTION_NAMESPACE and COLLECTION_PACKAGE to extract dynamically from galaxy.yml instead of hardcoded defaults. Removed template version handling and simplified collection build parameters. Eliminated templated variable injection into build templates.
Core Module Utilities
awx_collection/plugins/module_utils/controller_api.py, awx_collection/plugins/doc_fragments/auth_plugin.py
Added api_prefix parameter support for overriding API URL paths. Introduced _COLLECTION_FQCN canonical identifier (awx.awx) and derived _COLLECTION_TYPE property from FQCN split. Updated api_path() to conditionally return api_prefix when set.
Module Example Updates
awx_collection/plugins/modules/*.py (50+ modules), awx_collection/plugins/lookup/controller_api.py
Updated all example playbooks and documentation to reference fully-qualified collection names (awx.awx.module_name) instead of short module names. No functional logic changes; documentation/examples only.
Configuration and Documentation
awx_collection/README.md, awx_collection/galaxy.yml
Updated README with explicit config file path, example configurations, and revised release notes naming. Removed Ansible-managed header and build_ignore template entries from galaxy.yml.
Build Templates and Scripts
awx_collection/tools/replace_fqcn.sh, awx_collection/tools/roles/template_galaxy/...
Added new Bash script to migrate collection FQCN from awx.awx to ansible.controller during release branches. Removed templated README.md.j2 and galaxy.yml.j2 template files; replaced with minimal version-only update in template tasks.
Test Configuration
awx_collection/test/awx/conftest.py, awx_collection/test/awx/test_build_url.py, awx_collection/test/awx/test_module_utils.py, awx_collection/tests/sanity/ignore-*.txt
Updated fixture to accept monkeypatch and set CONTROLLER_OPTIONAL_API_URLPATTERN_PREFIX environment variable. Migrated test references from _COLLECTION_TYPE to _COLLECTION_FQCN. Added sanity check ignore entries for new replace_fqcn.sh script.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~90 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly describes the main changes: using fully-qualified collection names (FQCN) throughout and reducing dynamic templating in favor of release-based approach.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@github-actions github-actions bot added the component:awx_collection issues related to the collection for controlling AWX label Mar 10, 2026
The jinja2 templates for README and galaxy.yml are removed
In favor of this, a script is added with simplified goals
the script has the objective of:
- bulk replacing awx.awx with ansible.controller in source
- replacing special cases, mainly putting in version

A corresponding github actions test is added
this check will fail on tower PRs if the replacement
has not been ran

The script has not been ran, and will be done
in later commits
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
6 Security Hotspots
58.3% Coverage on New Code (required ≥ 80%)
E Maintainability Rating on New Code (required ≥ A)
C Reliability Rating on New Code (required ≥ A)
E Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@AlanCoding AlanCoding changed the title Use FQCN throughout collection, and reduce dynamic templating in favor of release-based AAP-68210 Use FQCN throughout collection, and reduce dynamic templating in favor of release-based Mar 11, 2026
@AlanCoding AlanCoding marked this pull request as ready for review March 11, 2026 17:00
@AlanCoding AlanCoding requested a review from adrisala March 11, 2026 17:00
Copy link
Member Author

Choose a reason for hiding this comment

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

I have strongly considered having the script delete itself after running. Just to put a finer point on the thought process here.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

def api_path(self, app_key=None):

if self.api_prefix:
return self.api_prefix
Copy link

Choose a reason for hiding this comment

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

api_prefix bypasses URL path normalization in api_path

Medium Severity

When self.api_prefix is set, api_path() returns it immediately, bypassing the normalization that ensures the path starts with / and ends with / (lines 664–668). A value like "api" or "api/controller" from a config file would produce a malformed URL in build_url(), while the same value set via CONTROLLER_OPTIONAL_API_URLPATTERN_PREFIX env var through the old code path would be properly normalized.

Fix in Cursor Fix in Web

Copy link
Member Author

Choose a reason for hiding this comment

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

I would rather not mess with it and let the user figure it out via the value of CONTROLLER_OPTIONAL_API_URLPATTERN_PREFIX. The more we try to automatically fix things, the more we own those problems.

# On upstream (awx) this is "awx.awx"; on downstream (tower) the
# replace_fqcn.sh script converts it to "ansible.controller".
# _COLLECTION_TYPE is derived from the FQCN automatically.
_COLLECTION_FQCN = "awx.awx"
Copy link
Member Author

Choose a reason for hiding this comment

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

This syntax change allows this line to get swept up in the general find+replace. It's dumb logic that takes all "awx.awx" and turns it into "ansible.controller".

This still leaves a special case for the version when packaging a collection.

So the collection FQCN is bulk-replaced by the script and it must go in a commit. Then the version is inserted in before building, every time.

Copy link

@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

Caution

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

⚠️ Outside diff range comments (2)
awx_collection/plugins/modules/schedule.py (1)

177-177: ⚠️ Potential issue | 🟡 Minor

Missing quotes around plugin name in query.

The plugin name awx.awx.schedule_rruleset should be quoted as a string, similar to line 169. Without quotes, Jinja2 will attempt variable attribute access instead of treating it as a plugin reference.

🐛 Proposed fix
-    rrule: "{{ query(awx.awx.schedule_rruleset, '2022-04-30 10:30:45', rules=rrules, timezone='UTC' ) | first }}"
+    rrule: "{{ query('awx.awx.schedule_rruleset', '2022-04-30 10:30:45', rules=rrules, timezone='UTC' ) | first }}"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@awx_collection/plugins/modules/schedule.py` at line 177, The query call
passing the plugin name awx.awx.schedule_rruleset is missing quotes and thus
will be interpreted as attribute access; update the template expression to quote
the plugin name (e.g., use "awx.awx.schedule_rruleset") in the rrule assignment
so Jinja2 treats it as a string plugin reference (match the quoted usage on the
earlier line around the existing query call).
awx_collection/plugins/modules/subscriptions.py (1)

62-75: ⚠️ Potential issue | 🟠 Major

Replace the example client_secret with an obvious placeholder.

These docs now publish a secret-looking token twice, and secret scanning is already flagging Line 66. Even if it is fake, keeping realistic secrets in examples creates avoidable leakage risk and CI noise.

Suggested doc-only fix
 EXAMPLES = '''
 - name: Get subscriptions
   awx.awx.subscriptions:
     client_id: "c6bd7594-d776-46e5-8156-6d17af147479"
-    client_secret: "MO9QUvoOZ5fc5JQKXoTch1AsTLI7nFsZ"
+    client_secret: "YOUR_CLIENT_SECRET"
 
 - name: Get subscriptions with a filter
   awx.awx.subscriptions:
     client_id: "c6bd7594-d776-46e5-8156-6d17af147479"
-    client_secret: "MO9QUvoOZ5fc5JQKXoTch1AsTLI7nFsZ"
+    client_secret: "YOUR_CLIENT_SECRET"
     filters:
       product_name: "Red Hat Ansible Automation Platform"
       support_level: "Self-Support"
 '''
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@awx_collection/plugins/modules/subscriptions.py` around lines 62 - 75, Update
the EXAMPLES string in subscriptions.py to remove the realistic-looking
client_secret values and replace them with an obvious placeholder (e.g.
REPLACE_WITH_CLIENT_SECRET or <CLIENT_SECRET>) so the example under the EXAMPLES
constant (which includes the client_id/client_secret pairs) no longer contains
secret-like tokens; ensure both occurrences of client_secret in the
multi-example block are updated to the placeholder.
🧹 Nitpick comments (4)
awx_collection/test/awx/conftest.py (1)

192-195: Scope the /api/ override more narrowly.

This shared fixture now forces every run_module test to bypass the default API-prefix resolution in controller_api.py/awxkit.py. That means regressions in the new FQCN-driven upstream/downstream path selection can still pass here. Prefer an opt-in fixture for tests that specifically need the standalone AWX server to stay on /api/.

As per coding guidelines, "Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

.github/workflows/ci.yml (1)

250-256: Consider reusing replace_fqcn.sh instead of duplicating sed logic.

This sed command duplicates the logic in awx_collection/tools/replace_fqcn.sh. If the replacement pattern needs to change (e.g., adding more file types or adjusting the pattern), both locations would need updating.

Consider invoking the script or extracting the pattern to avoid drift:

♻️ Potential refactor
       - name: Convert awx-operator playbooks to ansible.controller FQCN
         if: github.repository == 'ansible/tower'
         working-directory: awx-operator
         run: |
-          find molecule/ -type f \( -name '*.yml' -o -name '*.yaml' \) \
-            -exec sed -i 's/awx\.awx/ansible.controller/g' {} +
+          # Reuse the same replacement pattern as replace_fqcn.sh
+          ../awx/awx_collection/tools/replace_fqcn.sh molecule/
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 250 - 256, The CI step currently runs
an inline sed that duplicates the awx_collection/tools/replace_fqcn.sh logic;
replace that sed invocation with a call to the existing replace_fqcn.sh script
(or refactor both locations to source a shared pattern) so the FQCN replacement
is centralized—update the workflow step that runs the sed command to execute
replace_fqcn.sh (passing the target directory, e.g., molecule/) or call a small
wrapper that forwards arguments to replace_fqcn.sh and ensure the script handles
the same file globs and replacement pattern used by the current sed.
awx_collection/tools/replace_fqcn.sh (1)

23-24: Portability: sed -i without suffix fails on macOS.

The sed -i flag requires an empty suffix argument on BSD/macOS (sed -i '' ...). If this script is only intended to run in CI (Linux), this is acceptable. Otherwise, consider using a portable pattern:

♻️ Portable sed alternative
-    sed -i 's/^namespace: awx$/namespace: ansible/' "$COLLECTION_ROOT/galaxy.yml"
-    sed -i 's/^name: awx$/name: controller/' "$COLLECTION_ROOT/galaxy.yml"
+    sed -i.bak 's/^namespace: awx$/namespace: ansible/' "$COLLECTION_ROOT/galaxy.yml" && rm -f "$COLLECTION_ROOT/galaxy.yml.bak"
+    sed -i.bak 's/^name: awx$/name: controller/' "$COLLECTION_ROOT/galaxy.yml" && rm -f "$COLLECTION_ROOT/galaxy.yml.bak"

Or use a function:

portable_sed_i() {
    if [[ "$OSTYPE" == "darwin"* ]]; then
        sed -i '' "$@"
    else
        sed -i "$@"
    fi
}

Also applies to: 30-31

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

In `@awx_collection/tools/replace_fqcn.sh` around lines 23 - 24, The sed -i usage
in replace_fqcn.sh is not portable to macOS; replace the direct sed -i calls
(the two lines that run sed on "$COLLECTION_ROOT/galaxy.yml" and the other two
at 30-31) with a portable wrapper: add a portable_sed_i function that detects
darwin via OSTYPE and invokes sed -i '' on macOS and sed -i on other platforms,
then call portable_sed_i in place of the current sed -i invocations (referencing
the existing sed command occurrences in replace_fqcn.sh).
awx_collection/test/awx/test_module_utils.py (1)

74-76: Verify assert_any_call is intentional over assert_called_once_with.

The change from assert_called_once_with to assert_any_call is less strict—it only verifies the warning was called with these arguments at least once, rather than exactly once. If the test should ensure no spurious warnings, consider keeping the stricter assertion.

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

In `@awx_collection/test/awx/test_module_utils.py` around lines 74 - 76, The test
relaxed the check by using silence_warning.assert_any_call(...) instead of the
stricter silence_warning.assert_called_once_with(...); decide if the test must
ensure the warning is emitted exactly once and, if so, replace assert_any_call
with silence_warning.assert_called_once_with('You are running collection version
{0} but connecting to {1} version {2}'.format(my_module._COLLECTION_VERSION,
awx_name, ping_version)); if the intent is to allow multiple calls but still
ensure at least one occurrence, leave assert_any_call and add an explicit
assertEqual(silence_warning.call_count, 1) or a more precise check to enforce
the expected call count. Ensure you reference the silence_warning mock and the
formatted message in the assertion change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@awx_collection/plugins/module_utils/controller_api.py`:
- Around line 644-646: The method currently returns self.api_prefix verbatim,
causing inconsistency with default_api_path normalization; update the logic so
when self.api_prefix is set it is normalized to include a single trailing slash
(e.g., ensure it ends with "/" similar to how other paths are normalized) before
returning, preserving existing behavior when already correct; reference the
symbols self.api_prefix and default_api_path and make the change where the
api_prefix return occurs so endpoint matching code that relies on a trailing
slash receives a normalized value.

In `@awx_collection/README.md`:
- Around line 47-53: The fenced code block showing the YAML-like example (the
block containing "host: https://localhost:8043", "verify_ssl: true",
"oauth_token: <token>") should include a language specifier; update the opening
fence from ``` to ```yaml so the block becomes ```yaml ... ``` to match other
examples and enable proper syntax highlighting.

---

Outside diff comments:
In `@awx_collection/plugins/modules/schedule.py`:
- Line 177: The query call passing the plugin name awx.awx.schedule_rruleset is
missing quotes and thus will be interpreted as attribute access; update the
template expression to quote the plugin name (e.g., use
"awx.awx.schedule_rruleset") in the rrule assignment so Jinja2 treats it as a
string plugin reference (match the quoted usage on the earlier line around the
existing query call).

In `@awx_collection/plugins/modules/subscriptions.py`:
- Around line 62-75: Update the EXAMPLES string in subscriptions.py to remove
the realistic-looking client_secret values and replace them with an obvious
placeholder (e.g. REPLACE_WITH_CLIENT_SECRET or <CLIENT_SECRET>) so the example
under the EXAMPLES constant (which includes the client_id/client_secret pairs)
no longer contains secret-like tokens; ensure both occurrences of client_secret
in the multi-example block are updated to the placeholder.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 250-256: The CI step currently runs an inline sed that duplicates
the awx_collection/tools/replace_fqcn.sh logic; replace that sed invocation with
a call to the existing replace_fqcn.sh script (or refactor both locations to
source a shared pattern) so the FQCN replacement is centralized—update the
workflow step that runs the sed command to execute replace_fqcn.sh (passing the
target directory, e.g., molecule/) or call a small wrapper that forwards
arguments to replace_fqcn.sh and ensure the script handles the same file globs
and replacement pattern used by the current sed.

In `@awx_collection/test/awx/test_module_utils.py`:
- Around line 74-76: The test relaxed the check by using
silence_warning.assert_any_call(...) instead of the stricter
silence_warning.assert_called_once_with(...); decide if the test must ensure the
warning is emitted exactly once and, if so, replace assert_any_call with
silence_warning.assert_called_once_with('You are running collection version {0}
but connecting to {1} version {2}'.format(my_module._COLLECTION_VERSION,
awx_name, ping_version)); if the intent is to allow multiple calls but still
ensure at least one occurrence, leave assert_any_call and add an explicit
assertEqual(silence_warning.call_count, 1) or a more precise check to enforce
the expected call count. Ensure you reference the silence_warning mock and the
formatted message in the assertion change.

In `@awx_collection/tools/replace_fqcn.sh`:
- Around line 23-24: The sed -i usage in replace_fqcn.sh is not portable to
macOS; replace the direct sed -i calls (the two lines that run sed on
"$COLLECTION_ROOT/galaxy.yml" and the other two at 30-31) with a portable
wrapper: add a portable_sed_i function that detects darwin via OSTYPE and
invokes sed -i '' on macOS and sed -i on other platforms, then call
portable_sed_i in place of the current sed -i invocations (referencing the
existing sed command occurrences in replace_fqcn.sh).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 71a229dc-88dd-4e54-806e-46dc6e0c5e81

📥 Commits

Reviewing files that changed from the base of the PR and between 7e29f9e and b235b84.

📒 Files selected for processing (63)
  • .github/workflows/ci.yml
  • .github/workflows/promote.yml
  • Makefile
  • awx_collection/README.md
  • awx_collection/galaxy.yml
  • awx_collection/plugins/doc_fragments/auth_plugin.py
  • awx_collection/plugins/lookup/controller_api.py
  • awx_collection/plugins/module_utils/controller_api.py
  • awx_collection/plugins/modules/ad_hoc_command.py
  • awx_collection/plugins/modules/ad_hoc_command_cancel.py
  • awx_collection/plugins/modules/ad_hoc_command_wait.py
  • awx_collection/plugins/modules/bulk_host_create.py
  • awx_collection/plugins/modules/bulk_host_delete.py
  • awx_collection/plugins/modules/bulk_job_launch.py
  • awx_collection/plugins/modules/controller_meta.py
  • awx_collection/plugins/modules/credential.py
  • awx_collection/plugins/modules/credential_input_source.py
  • awx_collection/plugins/modules/credential_type.py
  • awx_collection/plugins/modules/execution_environment.py
  • awx_collection/plugins/modules/export.py
  • awx_collection/plugins/modules/group.py
  • awx_collection/plugins/modules/host.py
  • awx_collection/plugins/modules/import.py
  • awx_collection/plugins/modules/inventory.py
  • awx_collection/plugins/modules/inventory_source.py
  • awx_collection/plugins/modules/inventory_source_update.py
  • awx_collection/plugins/modules/job_cancel.py
  • awx_collection/plugins/modules/job_launch.py
  • awx_collection/plugins/modules/job_list.py
  • awx_collection/plugins/modules/job_template.py
  • awx_collection/plugins/modules/job_wait.py
  • awx_collection/plugins/modules/label.py
  • awx_collection/plugins/modules/license.py
  • awx_collection/plugins/modules/notification_template.py
  • awx_collection/plugins/modules/organization.py
  • awx_collection/plugins/modules/project.py
  • awx_collection/plugins/modules/project_update.py
  • awx_collection/plugins/modules/role.py
  • awx_collection/plugins/modules/role_definition.py
  • awx_collection/plugins/modules/role_team_assignment.py
  • awx_collection/plugins/modules/role_user_assignment.py
  • awx_collection/plugins/modules/schedule.py
  • awx_collection/plugins/modules/settings.py
  • awx_collection/plugins/modules/subscriptions.py
  • awx_collection/plugins/modules/team.py
  • awx_collection/plugins/modules/user.py
  • awx_collection/plugins/modules/workflow_approval.py
  • awx_collection/plugins/modules/workflow_job_template.py
  • awx_collection/plugins/modules/workflow_job_template_node.py
  • awx_collection/plugins/modules/workflow_launch.py
  • awx_collection/plugins/modules/workflow_node_wait.py
  • awx_collection/test/awx/conftest.py
  • awx_collection/test/awx/test_build_url.py
  • awx_collection/test/awx/test_module_utils.py
  • awx_collection/tests/sanity/ignore-2.14.txt
  • awx_collection/tests/sanity/ignore-2.15.txt
  • awx_collection/tests/sanity/ignore-2.16.txt
  • awx_collection/tests/sanity/ignore-2.17.txt
  • awx_collection/tools/replace_fqcn.sh
  • awx_collection/tools/roles/template_galaxy/tasks/main.yml
  • awx_collection/tools/roles/template_galaxy/templates/README.md.j2
  • awx_collection/tools/roles/template_galaxy/templates/galaxy.yml.j2
  • awx_collection/tools/template_galaxy.yml
💤 Files with no reviewable changes (3)
  • awx_collection/tools/roles/template_galaxy/templates/README.md.j2
  • awx_collection/galaxy.yml
  • awx_collection/tools/roles/template_galaxy/templates/galaxy.yml.j2

Comment on lines +644 to 646
if self.api_prefix:
return self.api_prefix
default_api_path = "/api/"
Copy link

@coderabbitai coderabbitai bot Mar 11, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check how api_prefix is used in tests and whether normalization is expected
rg -n "api_prefix" awx_collection/ -A3 -B3

Repository: ansible/awx

Length of output: 2622


🏁 Script executed:

#!/bin/bash
# Get the complete api_path method to see the trailing slash normalization
sed -n '642,680p' awx_collection/plugins/module_utils/controller_api.py | cat -n

Repository: ansible/awx

Length of output: 1857


🏁 Script executed:

#!/bin/bash
# Also search for how api_path and api_prefix are used in the codebase
rg -n "\.api_path\(|api_prefix" awx_collection/ --type py -A2 -B1 | head -100

Repository: ansible/awx

Length of output: 2038


🏁 Script executed:

#!/bin/bash
# Search for test cases and usage of api_prefix to understand expected format
rg -n "api_prefix\s*=" awx_collection/ --type py -A2 -B2 | head -60

Repository: ansible/awx

Length of output: 473


🏁 Script executed:

#!/bin/bash
# Check if there are any tests that demonstrate the issue or expected behavior
find awx_collection -name "*test*.py" -type f -exec grep -l "api_prefix" {} \;

Repository: ansible/awx

Length of output: 37


Add trailing slash normalization to api_prefix for consistency.

When api_prefix is set, the method returns it directly without the leading/trailing slash normalization applied to other paths (lines 23-27). If a caller passes api_prefix without a trailing slash (e.g., "/api" instead of "/api/"), URL construction will be inconsistent and may break at line 170 where endpoint matching occurs.

Either normalize api_prefix like the default paths, or document and validate that api_prefix must include trailing slashes.

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

In `@awx_collection/plugins/module_utils/controller_api.py` around lines 644 -
646, The method currently returns self.api_prefix verbatim, causing
inconsistency with default_api_path normalization; update the logic so when
self.api_prefix is set it is normalized to include a single trailing slash
(e.g., ensure it ends with "/" similar to how other paths are normalized) before
returning, preserving existing behavior when already correct; reference the
symbols self.api_prefix and default_api_path and make the change where the
api_prefix return occurs so endpoint matching code that relies on a trailing
slash receives a normalized value.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't wanna

Copy link

Choose a reason for hiding this comment

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

@AlanCoding, understood — no worries, acknowledged!

Comment on lines +47 to +53
or like this:

```
host: https://localhost:8043
verify_ssl: true
oauth_token: <token>
```
Copy link

@coderabbitai coderabbitai bot Mar 11, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add language specifier to fenced code block.

The code block on line 49 is missing a language specifier. For consistency with other code blocks in this file (which use no language but contain shell/ini), consider adding yaml since this example shows YAML format.

📝 Suggested fix
 or like this:
 
-```
+```yaml
 host: https://localhost:8043
 verify_ssl: true
 oauth_token: <token>
📝 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
or like this:
```
host: https://localhost:8043
verify_ssl: true
oauth_token: <token>
```
or like this:
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 49-49: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

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

In `@awx_collection/README.md` around lines 47 - 53, The fenced code block showing
the YAML-like example (the block containing "host: https://localhost:8043",
"verify_ssl: true", "oauth_token: <token>") should include a language specifier;
update the opening fence from ``` to ```yaml so the block becomes ```yaml ...
``` to match other examples and enable proper syntax highlighting.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is templated from the prior README.md.j2

This is not in the scope of the PR. All this does it materialize content already in the template to the duplicated file. This is the content already being used when building the collection.

I didn't start this to fix this problem, and it's noise.

Copy link

Choose a reason for hiding this comment

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

@AlanCoding, understood — this is pre-existing content from the template that the PR simply materializes, and fixing the missing language specifier is out of scope here. I'll note this for future reference.


📝 Learnings were identified and not saved (knowledge base disabled). Enable

@AlanCoding AlanCoding requested a review from thedoubl3j March 12, 2026 18:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component:awx_collection issues related to the collection for controlling AWX

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants