Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions collection/stages/roles/day2ops/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
# defaults file for day2ops
day2ops_steps: []
day2ops_report_filename: shiftstack-qa-day2ops-results.xml

# Application Credentials rotation
app_credential_name: "AppCreds-{{ user_cloud }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
# Source: https://github.com/shiftstack/installer/blob/master/docs/user/openstack/README.md#openstack-credentials-update
- name: Restore user/password auth to ensure full permissions for app credential creation
ansible.builtin.include_role:
name: shiftstack.stages.prepare
tasks_from: clouds.yml

- name: Create application credentials and update clouds.yaml
ansible.builtin.include_role:
name: shiftstack.stages.prepare
tasks_from: app_creds.yml

- name: Rotate OpenShift Cloud Credentials
ansible.builtin.shell: |
set -o pipefail && \
cat {{ clouds_yaml_file_path }} | sed 's/{{ user_cloud }}:/openstack:/' | \
oc set data -n kube-system secret/openstack-credentials clouds.yaml=-
environment:
KUBECONFIG: "{{ kubeconfig }}"
changed_when: true

- name: Get OpenStack Credentials from OCP cluster
ansible.builtin.shell: |
set -o pipefail && \
oc get secret -n kube-system openstack-credentials -o json | jq -r '.data."clouds.yaml"' | base64 -d
environment:
KUBECONFIG: "{{ kubeconfig }}"
register: ocp_creds_output
changed_when: false

- name: Parse OCP credentials
ansible.builtin.set_fact:
ocp_creds: "{{ ocp_creds_output.stdout | from_yaml }}"

- name: Verify credentials rotated to application credentials
ansible.builtin.assert:
that:
- ocp_creds.clouds.openstack.auth_type == 'v3applicationcredential'
fail_msg: "Credential rotation failed — auth_type is not v3applicationcredential"
success_msg: "Credential rotation verified — auth_type is v3applicationcredential"

- name: Wait until the Cluster Operators are healthy
ansible.builtin.include_role:
name: tools_cluster_checks
tasks_from: wait_until_cluster_operators_ready.yml
4 changes: 4 additions & 0 deletions collection/stages/roles/prepare/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ project:
load_balancers: 1000
load_balancer_listeners: 5000
load_balancer_pools: 5000
# Application Credentials
use_application_credentials: false
app_credential_name: "AppCreds-{{ user_cloud }}"

ocp_api_description: "API {{ ocp_cluster_name }}.{{ ocp_base_domain }}"
ocp_apps_description: "APPS {{ ocp_cluster_name }}.{{ ocp_base_domain }}"
ocp_bootstrap_fip_description: "Bootstrap {{ ocp_cluster_name }}.{{ ocp_base_domain }}"
Expand Down
76 changes: 76 additions & 0 deletions collection/stages/roles/prepare/tasks/app_creds.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
- name: Delete stale temporary Application Credential from interrupted previous run
ansible.builtin.shell: |
openstack application credential delete {{ app_credential_name }}-new
environment:
OS_CLOUD: "{{ user_cloud }}"
failed_when: false
changed_when: false

- name: Create new Application Credential
ansible.builtin.shell: |
openstack application credential create \
--description "App Creds - All roles" \
"{{ app_credential_name }}-new" -f yaml
environment:
OS_CLOUD: "{{ user_cloud }}"
register: app_cred_output
changed_when: true

- name: Parse Application Credential output
ansible.builtin.set_fact:
app_cred_info: "{{ app_cred_output.stdout | from_yaml }}"

- name: Read current clouds.yaml
ansible.builtin.slurp:
src: "{{ clouds_yaml_file_path }}"
register: clouds_yaml_file

- name: Set clouds.yaml fact
ansible.builtin.set_fact:
clouds_yaml_params: "{{ clouds_yaml_file.content | b64decode | from_yaml }}"

- name: Build updated cloud entry with application credentials
ansible.builtin.set_fact:
updated_cloud_entry:
auth:
auth_url: "{{ clouds_yaml_params.clouds[user_cloud].auth.auth_url }}"
application_credential_id: "{{ app_cred_info.id }}"
application_credential_secret: "{{ app_cred_info.secret }}"
auth_type: v3applicationcredential
identity_api_version: "{{ clouds_yaml_params.clouds[user_cloud].identity_api_version | default('3') }}"
region_name: "{{ clouds_yaml_params.clouds[user_cloud].region_name | default(omit) }}"

- name: Add cacert to updated cloud entry
ansible.builtin.set_fact:
updated_cloud_entry: "{{ updated_cloud_entry | combine({'cacert': clouds_yaml_params.clouds[user_cloud].cacert}, recursive=True) }}"
when: clouds_yaml_params.clouds[user_cloud].cacert is defined

- name: Update clouds.yaml with application credentials
ansible.builtin.set_fact:
clouds_yaml_params: "{{ {'clouds': (clouds_yaml_params.clouds | combine({user_cloud: updated_cloud_entry}))} }}"

- name: Write updated clouds.yaml
ansible.builtin.copy:
content: "{{ clouds_yaml_params | to_nice_yaml(indent=4) }}"
dest: "{{ clouds_yaml_file_path }}"
mode: u=rw,g=rw,o=r

- name: Update clouds.yaml copy in osp_config_dir
ansible.builtin.copy:
content: "{{ clouds_yaml_params | to_nice_yaml(indent=4) }}"
dest: "{{ osp_config_dir }}/clouds.yaml"
mode: u=rw,g=rw,o=r
when: osp_config_dir is defined

- name: Validate new application credentials work
openstack.cloud.auth:
cloud: "{{ user_cloud }}"

- name: Delete previous Application Credential
ansible.builtin.shell: |
openstack application credential delete {{ app_credential_name }}
environment:
OS_CLOUD: "{{ user_cloud }}"
failed_when: false
changed_when: false
4 changes: 4 additions & 0 deletions collection/stages/roles/prepare/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
- name: Update clouds.yml file with new Project
ansible.builtin.include_tasks: clouds.yml

- name: Configure Application Credentials for OpenStack authentication
ansible.builtin.include_tasks: app_creds.yml
when: use_application_credentials | default(false)

- name: Restricted Network Preparations
ansible.builtin.include_tasks: restricted_network.yml
when:
Expand Down
4 changes: 4 additions & 0 deletions jobs_definitions/osp_verification.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ stages:
- install
- post
- verification
- day2ops
- openstack_test
- lb_tests

day2ops_procedures:
- rotate_app_creds

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.

The day2ops stage is added but use_application_credentials isn't set (defaults to false). This means the cluster installs with user/password, then rotate_app_creds switches it to app creds as a day2 operation.

Is this the intended test flow? The Jenkins cp-migration multijob passes OPENSHIFT_OPENSTACK_APP_CREDS=True which enables BOTH prepare-time app creds AND day2ops rotation. If you want to test the prepare path too, add use_application_credentials: true here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yes, intentional for this PR — the test flow is: install with user/password, then rotate_app_creds switches to app creds as a day2 operation. This validates the rotation path. Enabling use_application_credentials: true for prepare-time testing can be added as a follow-up once the rotation path is proven in CI.


ocp_deployment_topology:
network_type: OVNKubernetes
primary_ip_protocol: ipv4 # ipv4 or ipv6
Expand Down