Skip to content

Update openstack credential - #656

Open
ssimpson89 wants to merge 6 commits into
ctrliq:mainfrom
ssimpson89:feature/openstack-application-credential
Open

Update openstack credential#656
ssimpson89 wants to merge 6 commits into
ctrliq:mainfrom
ssimpson89:feature/openstack-application-credential

Conversation

@ssimpson89

Copy link
Copy Markdown
Contributor
SUMMARY

Add Keystone application credential support to the OpenStack credential type.

The OpenStack credential type only supported Keystone password authentication: whatever was entered in the "Password (API Key)" field was sent through a v3 password login. Application credentials, the standard key-style credential in modern OpenStack (created via Horizon under Identity → Application Credentials or openstack application credential create), use a different Keystone auth method (v3applicationcredential) and therefore always failed with 401 Unauthorized regardless of the user's roles.

Changes:

  • Add optional application_credential_id and application_credential_secret inputs to the managed OpenStack credential type. When both are set, the generated clouds.yaml uses auth_type: v3applicationcredential and omits user/project/domain scoping, which Keystone rejects in combination with application credentials. Password auth behavior is unchanged when the new fields are not set.
  • Relax required inputs to host only, since the two auth methods are alternatives. This follows the design of the managed Azure credential type, which carries both password and service-principal field groups as optional inputs and branches in the injector on which group is present.
  • Order the fields so the credential form (three fields per row) renders each auth mode as its own row group, and mark the scoping fields as ignored in application-credential mode via help text.
  • Document both authentication methods, every field, and common scenarios in the credentials user guide; note in the inventory source docs that both methods work with the native OpenStack source.

No migration is required: managed credential type inputs are served from the in-code registry, so existing installs pick up the new fields on upgrade. Existing OpenStack credentials are unaffected.

Validation:

  • Unit and functional tests added/updated; all 22 openstack-related tests pass.
  • End-to-end against a live OpenStack 2025.1 (Epoxy) deployment: a native OpenStack inventory source using an application credential (member role) authenticates and imports hosts; the same credential through the old password path reproduces the 401.
ISSUE TYPE
  • New or Enhanced Feature
COMPONENT NAME
  • API
  • Docs
ASCENDER VERSION
25.5.1-25-gb4876c0e
ADDITIONAL INFORMATION

Code changes were made using Claude Code. Verified via Claude as well as manually.

ssimpson89 and others added 4 commits August 11, 2026 17:26
The OpenStack credential type only supported Keystone password auth:
whatever was entered in the Password (API Key) field was sent through
a v3 password login, so application credentials (the standard
key-style credential in modern OpenStack) always failed with
Unauthorized regardless of the user's roles.

Add optional application_credential_id/application_credential_secret
inputs. When both are set, the generated clouds.yaml uses
auth_type: v3applicationcredential and omits user/project scoping
fields, which Keystone rejects in combination with application
credentials. Password auth behavior is unchanged when the new fields
are not set. Required inputs are relaxed to host only, since the two
auth methods are alternatives.

Refs upstream ansible/awx#14401.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHxL2MTgkUzA4BCPGqs3hJ
The credential form renders three fields per row in definition order,
so field order is the only visual grouping available. Order rows as:
shared endpoint + password identity, password scoping, application
credential + region. Also mark the scoping fields as ignored in
application-credential mode via help text.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHxL2MTgkUzA4BCPGqs3hJ
Rewrite the OpenStack credential docs to describe the two supported
authentication methods (Keystone password and application credential),
explain every field and which method it applies to, note the fields
ignored in application-credential mode, and describe common scenarios
including the save-time vs launch-time validation behavior. Note in
the inventory source docs that both auth methods work with the native
OpenStack source.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHxL2MTgkUzA4BCPGqs3hJ
Tighten the field descriptions to reference-manual voice, make the
auth-method group headers parallel, note that application credential
secrets are shown only at creation time, and update the form
screenshot to show both authentication methods.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHxL2MTgkUzA4BCPGqs3hJ
Copilot AI lite review requested due to automatic review settings August 12, 2026 20:50

Copilot AI left a comment

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.

Pull request overview

Adds Keystone application-credential authentication support to Ascender’s managed OpenStack credential type, enabling modern OpenStack deployments to authenticate successfully (and documenting the two supported auth flows).

Changes:

  • Extend the OpenStack managed credential type with application_credential_id/application_credential_secret inputs and update the injector to emit auth_type: v3applicationcredential when those are provided.
  • Relax OpenStack credential required inputs to host (auth URL) and update unit/functional tests accordingly.
  • Update user-guide documentation to describe both authentication modes and how they apply to inventory sources.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
docs/docsite/rst/userguide/inventories.rst Notes that the OpenStack inventory source works with both password and application-credential auth.
docs/docsite/rst/userguide/credentials.rst Documents OpenStack credential fields and usage for both auth methods.
awx/main/tests/unit/test_tasks.py Adds unit test coverage for generated clouds.yaml when using application credentials.
awx/main/tests/functional/api/test_credential.py Updates required-field expectations and adds API coverage for creating app-credential-based OpenStack credentials.
awx/main/models/credential/injectors.py Implements injector branching to emit v3applicationcredential auth and omit scope fields when app creds are used.
awx/main/models/credential/init.py Adds the new managed credential fields and updates required inputs for OpenStack.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread awx/main/models/credential/__init__.py
Address Copilot review: the host field's example URL was v2.0-style,
which does not work with application credential auth. Update the help
text example to a v3 URL and refresh the form screenshot to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHxL2MTgkUzA4BCPGqs3hJ
Copilot AI review requested due to automatic review settings August 12, 2026 21:11

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (1)

awx/main/models/credential/injectors.py:77

  • _openstack_data() will fall back to password auth whenever both application credential fields are not present, and it uses default='' for username/password/project. This can silently generate a clouds.yaml with empty auth values (e.g., host set but no auth inputs), leading to confusing runtime failures instead of a clear configuration error. It also treats a partially-filled application credential (ID without secret, or vice versa) as password auth.

Consider explicitly validating that either (application_credential_id + application_credential_secret) OR (username + password + project) is provided before building the auth dict, and raise a clear exception if the inputs are incomplete.

    use_app_cred = cred.has_input('application_credential_id') and cred.has_input('application_credential_secret')
    if use_app_cred:

The injector reference test fills every credential input, which now
switches the openstack injector into application-credential mode and
no longer matches the password-auth reference file. Pop the
application credential inputs in the fixture, matching the existing
ascender/oauth_token pattern for mutually exclusive inputs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHxL2MTgkUzA4BCPGqs3hJ
Copilot AI review requested due to automatic review settings August 12, 2026 21:27

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated no new comments.

Suppressed comments (1)

awx/main/models/credential/init.py:755

  • The inline comment about form field ordering says rows are grouped purely by auth mode, but with the 3-fields-per-row layout the region and verify_ssl shared options end up in/after the application-credential row. Tweaking the comment to match the actual grouping will avoid confusing future maintainers when adjusting field order.
            # Form renders three fields per row, in order. Rows are grouped by
            # auth mode: shared + password identity / password scoping / application credential.

Copilot AI review requested due to automatic review settings August 12, 2026 22:16
@ssimpson89

ssimpson89 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

One of the two CI failures is addressed here; the other is pre-existing and left alone deliberately.

test_inventory_update_injected_content[openstack] — caused by this PR, fixed in f77eb88. The fixture fills every credential input with fake values, which now populates both application credential fields and switches the injector into v3applicationcredential mode, so the generated clouds.yaml no longer matched the password-auth reference file. The fixture now pops those two inputs, matching the existing precedent for the ascender source's mutually exclusive oauth_token.

test_proxy_ip_allowed — not caused by this PR and not fixed here, flagging it for maintainers. The test PATCHes PROXY_IP_ALLOWED_LIST and asserts the new value applies to the next request, without clearing the settings cache first. The suite runs under pytest -n auto --dist=loadfile, which deals test files to workers as they are collected, so the file-to-worker distribution shifts whenever the collected test count changes: main collects 3745 items, this branch collects 3756. That reshuffle puts test_generic.py after a file that leaves settings cached on the same worker, and the stale read fails the assertion deterministically (it failed on gw0 and gw1 across separate runs, so a re-run will not clear it).

Adding cache.clear() at the top of that test makes it pass, verified locally against the exact CI invocation, but that is an unrelated test file and the better fix may be in whichever file leaks the cached settings. Happy to include either change here if a maintainer prefers, or to open it separately.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated no new comments.

@ssimpson89
ssimpson89 force-pushed the feature/openstack-application-credential branch from 18f170c to f77eb88 Compare August 13, 2026 13:20
Copilot AI review requested due to automatic review settings August 13, 2026 13:20

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated no new comments.

Suppressed comments (3)

awx/main/models/credential/injectors.py:86

  • With inputs['required'] relaxed to ['host'], the password-auth branch can now generate a clouds.yaml with empty username/password/project_name (because get_input(..., default='') will fill blanks). This tends to produce confusing runtime auth failures; it would be better to fail fast when password auth is selected but required fields are missing.
    else:
        openstack_auth = dict(
            auth_url=cred.get_input('host', default=''),

awx/main/tests/unit/test_tasks.py:317

  • Typo in the test fixture value: secrete should be secret (it reads like an accidental misspelling and can distract when scanning failures).
        'password': 'secrete',

docs/docsite/rst/userguide/credentials.rst:589

  • The docs say a credential with neither username/password nor an application credential “fails at job or inventory sync launch time”, but with OpenStack required inputs now set to ['host'] the launch-time validation no longer guarantees this. Consider rewording to reflect that the failure happens when authentication is attempted during execution/sync.
- A credential that provides neither a username/password pair nor an application credential is
  accepted when saved but fails at job or inventory sync launch time.

@TheWitness
TheWitness requested a review from cigamit August 17, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants