Skip to content

Fix rotate_app_creds YAML parsing when from_yaml returns a list#19

Open
tusharjadhav3302 wants to merge 2 commits into
mainfrom
fix-ocp-creds-yaml-parsing
Open

Fix rotate_app_creds YAML parsing when from_yaml returns a list#19
tusharjadhav3302 wants to merge 2 commits into
mainfrom
fix-ocp-creds-yaml-parsing

Conversation

@tusharjadhav3302

Copy link
Copy Markdown
Contributor

Summary

Fix the rotate_app_creds day2ops procedure failing at the credential verification step with:
'list object' has no attribute 'clouds'

Why

The to_nice_yaml(indent=4) filter prepends ---\n to the clouds.yaml content. When this content is piped into the OCP openstack-credentials secret via oc set data, the secret stores the YAML document separator. On readback, Ansible's from_yaml interprets the ----prefixed content as a multi-document YAML and returns a list (with one element) instead of a dict.
The verification assert then fails because it expects ocp_creds.clouds.openstack.auth_type but ocp_creds is a list, not a mapping.

What failed

Task: Verify credentials rotated to application credentials
Error from Zuul job (shiftstack-rhel9-rhoso18.0-ocp421, Jun 30):
The conditional check 'ocp_creds.clouds.openstack.auth_type == 'v3applicationcredential'' failed. The error was: error while evaluating conditional (ocp_creds.clouds.openstack.auth_type == 'v3applicationcredential'): 'list object' has no attribute 'clouds'. 'list object' has no attribute 'clouds'

Note: The credential rotation itself succeeds — the secret IS correctly updated. Only the verification readback parsing fails.

How

Two fixes applied to rotate_app_creds.yml:

1. Prevention — strip --- before writing to the secret:

# Before (buggy):
cat {{ clouds_yaml_file_path }} | sed 's/{{ user_cloud }}:/openstack:/' | \
oc set data -n kube-system secret/openstack-credentials clouds.yaml=-

# After (fixed):
cat {{ clouds_yaml_file_path }} | sed '/^---$/d' | sed 's/{{ user_cloud }}:/openstack:/' | \
oc set data -n kube-system secret/openstack-credentials clouds.yaml=-

2. Defensive parsing — handle both list and dict from from_yaml:

# Before (buggy):
- name: Parse OCP credentials
  ansible.builtin.set_fact:
    ocp_creds: "{{ ocp_creds_output.stdout | from_yaml }}"

# After (fixed):
- name: Parse OCP credentials
  vars:
    parsed_yaml: "{{ ocp_creds_output.stdout | from_yaml }}"
  ansible.builtin.set_fact:
    ocp_creds: "{{ (parsed_yaml is mapping) | ternary(parsed_yaml, parsed_yaml[0]) }}"

Test Plan

  • ansible-lint passes (production profile)
  • Day2ops rotation passes on a running OCP cluster
  • oc get secret -n kube-system openstack-credentials content has no leading ---
  • ocp_creds correctly parsed as dict with auth_type: v3applicationcredential

References

Bug: https://redhat.atlassian.net/browse/OCPBUGS-95045
Parent feature: https://redhat.atlassian.net/browse/OSPRH-6485
Failing job: shiftstack-rhel9-rhoso18.0-ocp421 periodic run (Jun 30, 2026)

The clouds.yaml stored in the OCP secret starts with '---' (from
to_nice_yaml), causing from_yaml to return a list instead of a dict.
Strip the document separator before piping to the secret and handle
both list/dict cases when parsing the verification readback.

OSPRH-6485

Co-authored-by: Cursor <cursoragent@cursor.com>
@tusharjadhav3302 tusharjadhav3302 added the ready-for-review PR is ready for code review label Jul 1, 2026
…late (PR #20)

Cherry-picked from fix-omit-leak-install-config branch to unblock CI.
Without this fix, openshift-install fails immediately with:
  "platform.openstack.controlPlanePort.fixedIPs[0].subnet.id:
   Invalid value: __omit_place_holder__...: invalid subnet ID"

The omit sentinel leaks because default(omit) only works in Ansible
module parameters, not in vars passed to ansible.builtin.template.
This fix uses empty defaults and truthiness checks instead.

OCPBUGS-95045

Co-authored-by: Cursor <cursoragent@cursor.com>

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

lgtm. Two things, please:

  1. Rebase on main - #20 is merged, so the cherry-picked install-config commit is already on main. A rebase should drop it cleanly.

  2. Testing - could you check the test plan boxes or link a CI run showing the rotation succeeds with the fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-review PR is ready for code review

Development

Successfully merging this pull request may close these issues.

2 participants