Skip to content

Commit 282304a

Browse files
committed
Add PTP GM test run
1 parent 2d5bd7e commit 282304a

2 files changed

Lines changed: 369 additions & 0 deletions

File tree

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
---
2+
# Disclaimer:
3+
# This playbook is not officially supported and comes with no guarantees.
4+
# Use it at your own risk. Ensure you test thoroughly in your environment
5+
# before deploying to production.
6+
7+
# -----------------------------------------------------------------------------
8+
# Playbook Name: Deploy RAN PTP GM tests script
9+
# Description : Prepares a bastion host to run RAN PTP GM eco-gotests.
10+
# Optionally discovers the spoke kubeconfig and BMC IP from the
11+
# hub ACM cluster. Mirrors required images, pulls the eco-gotests
12+
# container, and generates a single test script that runs:
13+
# 1. containernshide, powermanagement, deploymenttypes
14+
# (with existing ZTP PtpConfigs)
15+
# 2. For each ptp_cycle_config: switches PTP config, waits 5m,
16+
# runs ptp eco-gotests
17+
#
18+
# Prerequisites:
19+
# - Either kubeconfig is provided directly, or hub_kubeconfig +
20+
# spoke_cluster_label_selector are provided for spoke discovery.
21+
# - hub_kubeconfig must be the path to the hub kubeconfig file on the bastion
22+
# (used for spoke discovery and mounted into the eco-gotests container).
23+
# - ptp_cycle_configs must be a list of {name, urls[]} dicts.
24+
# - bmc_user and bmc_password must be defined for power management tests.
25+
#
26+
# Key Tasks:
27+
# - Optionally discover spoke kubeconfig and BMC IP from hub ManagedCluster
28+
# - Gather cluster version from OpenShift
29+
# - Pull the eco-gotests container (mirror to disconnected registry if needed)
30+
# - Generate a unified test script covering all eco_gotests_features and
31+
# ptp_cycle_configs
32+
33+
# Usage (hub/spoke ACM discovery mode):
34+
# ansible-playbook ./playbooks/ran/deploy-ptp-gm-tests-script.yaml \
35+
# -i ./inventories/ocp-deployment/build-inventory.py \
36+
# --extra-vars "hub_kubeconfig=/home/telcov10n/project/generated/kni-qe-111/auth/kubeconfig \
37+
# hub_clusterconfigs_path=/home/telcov10n/project/generated/kni-qe-111 \
38+
# spoke_cluster_label_selector=sites=helix48 \
39+
# bmc_user=<user> bmc_password=<pass> \
40+
# labels='!no-container' \
41+
# ptp_cycle_configs='[{\"name\": \"ntpfailover\", \"urls\": [
42+
# \"https://gitlab.cee.redhat.com/telcov10n/ztp-site-configs-ci/-/raw/ptp_gm/policygentemplates/4.20/ptp-test/PtpConfigGmWpcNtpCustom.yaml\",
43+
# \"https://gitlab.cee.redhat.com/telcov10n/ztp-site-configs-ci/-/raw/ptp_gm/policygentemplates/4.20/ptp-test/PtpConfigSlaveNtpCustom.yaml\"
44+
# ]}]'"
45+
#
46+
# Available extra-vars:
47+
# hub_kubeconfig # string: Path to hub kubeconfig file on the bastion (enables spoke discovery
48+
# # and is mounted directly into the eco-gotests container).
49+
# spoke_cluster_label_selector # string: Label selector for spoke ManagedCluster (required with hub_kubeconfig).
50+
# bmc_user # string: BMC username (required for power management tests).
51+
# bmc_password # string: BMC password (required for power management tests).
52+
# kubeconfig # string: Path to spoke kubeconfig (alternative to hub_kubeconfig discovery).
53+
# spoke_kubeconfig # string: Same as kubeconfig, used for oc commands between PTP cycles.
54+
# labels # string: Test labels filter (e.g. !no-container).
55+
# ptp_cycle_configs # list: [{name, urls[]}] PTP config cycles to run after ZTP features.
56+
# # Example: ptp_cycle_configs='[{"name": "ntpfailover", "urls": [
57+
# # "https://gitlab.cee.redhat.com/telcov10n/ztp-site-configs-ci/-/raw/ptp_gm/policygentemplates/4.20/ptp-test/PtpConfigGmWpcNtpCustom.yaml",
58+
# # "https://gitlab.cee.redhat.com/telcov10n/ztp-site-configs-ci/-/raw/ptp_gm/policygentemplates/4.20/ptp-test/PtpConfigSlaveNtpCustom.yaml"
59+
# # ]}]'
60+
# eco_gotests_features # list: Features to run in the first cycle (with ZTP PtpConfigs).
61+
# # Supported values: containernshide, powermanagement, deploymenttypes.
62+
# # Defaults to all three. Example: eco_gotests_features='["containernshide","powermanagement"]'
63+
# eco_gotests_tag # string: Override image tag (e.g. "latest", "v4.18.0"). Auto-detects from cluster version if not set.
64+
# eco_gotest_base_dir # string: Base directory for PTP cycle reports (default: /tmp/eco_gotests_ptp_gm).
65+
# test_timeout # string: Per-cycle timeout (default: 12h).
66+
# mirror_registry # string: Disconnected registry URL host:port.
67+
# cnf_test_image # string: Override ECO_CNF_RAN_TEST_IMAGE passed to the eco-gotests container.
68+
# additional_test_env_variables # string: Additional env variables for the eco-gotests container (PTP cycles).
69+
70+
- name: Deploy RAN PTP GM tests script
71+
hosts: bastion
72+
gather_facts: true
73+
vars:
74+
eco_gotests_image: quay.io/ocp-edge-qe/eco-gotests
75+
eco_gotest_base_dir: /tmp/eco_gotests_ptp_gm
76+
test_timeout: "12h"
77+
script_name: "eco-gotests-ptp-gm-run.sh"
78+
pull_container_image: true
79+
mirror_registry: ""
80+
additional_test_env_variables: ""
81+
auth_kubeconfig_path: "/tmp/auth_kubeconfigs"
82+
eco_gotests_features:
83+
- containernshide
84+
- powermanagement
85+
- deploymenttypes
86+
tasks:
87+
- name: Ensure required variables are defined
88+
ansible.builtin.assert:
89+
that:
90+
- (hub_kubeconfig is defined and spoke_cluster_label_selector is defined) or kubeconfig is defined
91+
- labels is defined
92+
- ptp_cycle_configs is defined
93+
94+
- name: Set up kubeconfig directory and discover spoke
95+
when: hub_kubeconfig is defined
96+
block:
97+
- name: Ensure auth_kubeconfig_path directory does not exist
98+
ansible.builtin.file:
99+
path: "{{ auth_kubeconfig_path }}"
100+
state: absent
101+
102+
- name: Ensure auth_kubeconfig directory is present
103+
ansible.builtin.file:
104+
path: "{{ auth_kubeconfig_path }}/spokes"
105+
state: directory
106+
recurse: true
107+
mode: "0777"
108+
109+
- name: Get managed cluster (spoke)
110+
kubernetes.core.k8s_info:
111+
api_version: cluster.open-cluster-management.io/v1
112+
kind: ManagedCluster
113+
kubeconfig: "{{ hub_kubeconfig }}"
114+
label_selectors: "{{ spoke_cluster_label_selector }}"
115+
register: spoke_cluster_info
116+
117+
- name: Get spoke admin kubeconfig secret
118+
kubernetes.core.k8s_info:
119+
api_version: v1
120+
kind: Secret
121+
name: "{{ spoke_cluster_info.resources[0].metadata.name }}-admin-kubeconfig"
122+
namespace: "{{ spoke_cluster_info.resources[0].metadata.name }}"
123+
kubeconfig: "{{ hub_kubeconfig }}"
124+
register: spoke_kubeconfig_secret
125+
126+
- name: Get BMC address of spoke
127+
kubernetes.core.k8s_info:
128+
api_version: metal3.io/v1alpha1
129+
kind: BareMetalHost
130+
namespace: "{{ spoke_cluster_info.resources[0].metadata.name }}"
131+
kubeconfig: "{{ hub_kubeconfig }}"
132+
register: spoke_bmc_host
133+
134+
- name: Extract BMC IP from spoke BMC address
135+
ansible.builtin.set_fact:
136+
spoke_bmc_ip: "{{ spoke_bmc_host.resources[0].spec.bmc.address | regex_search('\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}') }}"
137+
138+
- name: Write spoke kubeconfig to test directory
139+
ansible.builtin.copy:
140+
content: "{{ spoke_kubeconfig_secret.resources[0].data.kubeconfig | b64decode }}"
141+
dest: "{{ auth_kubeconfig_path }}/spokes/spoke-kubeconfig"
142+
mode: "0600"
143+
144+
- name: Set kubeconfig from discovered spoke
145+
ansible.builtin.set_fact:
146+
kubeconfig: "{{ auth_kubeconfig_path }}/spokes/spoke-kubeconfig"
147+
spoke_kubeconfig: "{{ auth_kubeconfig_path }}/spokes/spoke-kubeconfig"
148+
149+
- name: Ensure base directory does not exist
150+
ansible.builtin.file:
151+
path: "{{ eco_gotest_base_dir }}"
152+
state: absent
153+
154+
- name: Ensure base directory is present
155+
ansible.builtin.file:
156+
path: "{{ eco_gotest_base_dir }}"
157+
state: directory
158+
mode: "0760"
159+
160+
- name: Gather cluster network information
161+
register: cluster_info
162+
environment:
163+
K8S_AUTH_KUBECONFIG: "{{ kubeconfig }}"
164+
kubernetes.core.k8s_info:
165+
api: operator.openshift.io/v1
166+
kind: Network
167+
name: cluster
168+
169+
- name: Extract OpenShift version details
170+
ansible.builtin.set_fact:
171+
version: "{{ cluster_info.resources[0].status.version.split('.')[0] }}.{{ cluster_info.resources[0].status.version.split('.')[1] }}"
172+
173+
- name: Print cluster version
174+
ansible.builtin.debug:
175+
msg: "Cluster version: {{ version }}"
176+
177+
- name: Mirror eco-gotests image to disconnected registry
178+
when: mirror_registry | default('') | length > 0
179+
block:
180+
- name: Set eco-gotests mirror tag
181+
ansible.builtin.set_fact:
182+
eco_gotests_tag: "{{ eco_gotests_tag | default('v' ~ version ~ '.0') }}"
183+
184+
- name: Copy eco-gotests image to disconnected registry
185+
ansible.builtin.command: >
186+
skopeo copy
187+
--dest-tls-verify=false
188+
docker://{{ eco_gotests_image }}:{{ eco_gotests_tag }}
189+
docker://{{ mirror_registry }}/{{ eco_gotests_image.split('/')[1:] | join('/') }}:{{ eco_gotests_tag }}
190+
register: skopeo_result
191+
changed_when: skopeo_result.rc == 0
192+
193+
- name: Override eco-gotests image source to disconnected registry
194+
ansible.builtin.set_fact:
195+
eco_gotests_image: "{{ mirror_registry }}/{{ eco_gotests_image.split('/')[1:] | join('/') }}"
196+
197+
- name: Mirror PTP images to disconnected registry
198+
when: mirror_registry | default('') | length > 0
199+
block:
200+
- name: Write pull secret auth file for registry mirroring
201+
no_log: true
202+
ansible.builtin.copy:
203+
content: "{{ pull_secret_string | b64decode }}"
204+
dest: "{{ pull_secret_file | default('/tmp/auth.json') }}"
205+
mode: '0600'
206+
207+
- name: Mirror cloud-event-consumer v1 image
208+
ansible.builtin.command: >
209+
skopeo copy
210+
--dest-tls-verify=false
211+
--all
212+
docker://quay.io/redhat-cne/cloud-event-consumer:4.18
213+
docker://{{ mirror_registry }}/ran-test/cloud-event-consumer:v1
214+
register: skopeo_v1_result
215+
changed_when: skopeo_v1_result.rc == 0
216+
217+
- name: Mirror cloud-event-consumer v2 image
218+
ansible.builtin.command: >
219+
skopeo copy
220+
--dest-tls-verify=false
221+
--all
222+
docker://quay.io/redhat-cne/cloud-event-consumer:latest
223+
docker://{{ mirror_registry }}/ran-test/cloud-event-consumer:v2
224+
register: skopeo_v2_result
225+
changed_when: skopeo_v2_result.rc == 0
226+
227+
- name: Mirror ptp-must-gather image (OCP < 4.21 only)
228+
when: version.split('.')[1] | int < 21
229+
ansible.builtin.command: >
230+
skopeo copy
231+
--dest-tls-verify=false
232+
--all
233+
--authfile {{ pull_secret_file | default('/tmp/auth.json') }}
234+
docker://registry.redhat.io/openshift4/ptp-must-gather-rhel9:v{{ version }}
235+
docker://{{ mirror_registry }}/ran-test/ptp-must-gather:v{{ version }}
236+
register: skopeo_must_gather_result
237+
changed_when: skopeo_must_gather_result.rc == 0
238+
239+
- name: Set PTP event consumer mirror fact
240+
ansible.builtin.set_fact:
241+
ptp_event_consumer_image: "{{ mirror_registry }}/ran-test/cloud-event-consumer"
242+
243+
- name: Set PTP must-gather mirror fact (OCP < 4.21 only)
244+
when: version.split('.')[1] | int < 21
245+
ansible.builtin.set_fact:
246+
ptp_must_gather_image: "{{ mirror_registry }}/ran-test/ptp-must-gather:v{{ version }}"
247+
248+
- name: Remove eco-gotests image
249+
when: pull_container_image is true
250+
containers.podman.podman_image:
251+
name: "{{ eco_gotests_image }}"
252+
state: absent
253+
tag: "{{ item }}"
254+
loop: "{{ (['v' + version + '.0', 'latest'] + ([eco_gotests_tag] if eco_gotests_tag is defined else [])) | unique }}"
255+
256+
- name: Pull user-specified eco-gotests image
257+
when: eco_gotests_tag is defined and pull_container_image is true
258+
containers.podman.podman_image:
259+
name: "{{ eco_gotests_image }}"
260+
tag: "{{ eco_gotests_tag }}"
261+
262+
- name: Try pulling cluster version matched image, fallback to latest if it fails
263+
when: eco_gotests_tag is not defined and pull_container_image is true
264+
block:
265+
- name: Pull a cluster version matched eco-gotests image
266+
containers.podman.podman_image:
267+
name: quay.io/ocp-edge-qe/eco-gotests
268+
tag: v{{ version }}.0
269+
270+
- name: Set tag to specific version
271+
ansible.builtin.set_fact:
272+
eco_gotests_tag: "v{{ version }}.0"
273+
274+
rescue:
275+
- name: Pull latest version of eco-gotests image as fallback
276+
containers.podman.podman_image:
277+
name: quay.io/ocp-edge-qe/eco-gotests
278+
tag: latest
279+
280+
- name: Set tag to latest
281+
ansible.builtin.set_fact:
282+
eco_gotests_tag: latest
283+
284+
- name: Set eco-gotests feature configurations
285+
ansible.builtin.set_fact:
286+
_eco_gotests_feature_configs:
287+
- name: containernshide
288+
additional_test_env_variables: >-
289+
-e ECO_TEST_TRACE=true
290+
-e ECO_VERBOSE_SCRIPT=true
291+
- name: powermanagement
292+
additional_test_env_variables: >-
293+
-e ECO_CNF_RAN_BMC_USERNAME={{ bmc_user | default('') }}
294+
-e ECO_CNF_RAN_BMC_PASSWORD={{ bmc_password | default('') }}
295+
-e ECO_CNF_RAN_BMC_HOSTS={{ spoke_bmc_ip | default('') }}
296+
-e ECO_TEST_TRACE=true
297+
-e ECO_VERBOSE_SCRIPT=true
298+
- name: deploymenttypes
299+
additional_test_env_variables: >-
300+
-e ECO_CNF_RAN_SKIP_TLS_VERIFY=true
301+
-e ECO_TEST_TRACE=true
302+
-e ECO_VERBOSE_SCRIPT=true
303+
304+
- name: Generate PTP GM test execution script
305+
ansible.builtin.template:
306+
src: templates/run_eco_gotests_ptp_gm.j2
307+
dest: "{{ eco_gotest_base_dir }}/{{ script_name }}"
308+
mode: "0764"
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/bin/bash
2+
3+
{% macro podman_run(feat, reports_dir, extra_env='') %}
4+
podman run -it --rm --net=host --uidmap 0:1:1000 --uidmap 1000:0:1 --uidmap 1001:1001:64536 --gidmap 0:1:1000 --gidmap 1000:0:1 --gidmap 1001:1001:64536 \
5+
-e KUBECONFIG=/kubeconfig/kubeconfig \
6+
-e ECO_REPORTS_DUMP_DIR=/tmp/reports \
7+
-e ECO_VERBOSE_LEVEL=100 \
8+
-e ECO_TEST_VERBOSE=true \
9+
-e ECO_DUMP_FAILED_TESTS=true \
10+
-e REPORT_CASE_TAG={{ report_test_case_tag | default('') }} \
11+
-e REPORT_PARAMETER_TAG={{ report_parameter_tag | default('') }} \
12+
-e ECO_TC_PREFIX={{ report_tc_prefix | default('') }} \
13+
-e ECO_TEST_FEATURES={{ feat }} \
14+
-e ECO_TEST_LABELS={{ labels }} \
15+
{% if hub_kubeconfig is defined and hub_kubeconfig | length > 0 %}-e ECO_CNF_RAN_KUBECONFIG_HUB=/kubeconfig/hub-kubeconfig \
16+
{% endif %}
17+
{% if cnf_test_image is defined and cnf_test_image | length > 0 %}-e ECO_CNF_RAN_TEST_IMAGE={{ cnf_test_image }} \
18+
{% endif %}
19+
{% if feat == 'ptp' and ptp_event_consumer_image is defined %}-e ECO_CNF_RAN_PTP_EVENT_CONSUMER_IMAGE={{ ptp_event_consumer_image }} \
20+
-e ECO_CNF_RAN_PTP_EVENT_CONSUMER_V1_TAG=:v1 \
21+
-e ECO_CNF_RAN_PTP_EVENT_CONSUMER_V2_TAG=:v2 \
22+
{% endif %}
23+
{% if feat == 'ptp' and ptp_must_gather_image is defined %}-e ECO_CNF_RAN_PTP_MUST_GATHER_IMAGE={{ ptp_must_gather_image }} \
24+
{% endif %}
25+
{% if extra_env | length > 0 %}{{ extra_env }} \
26+
{% endif %}
27+
-v {{ kubeconfig }}:/kubeconfig/kubeconfig:Z \
28+
-v {{ reports_dir }}:/tmp/reports:Z \
29+
{% if hub_kubeconfig is defined and hub_kubeconfig | length > 0 %}-v {{ hub_kubeconfig }}:/kubeconfig/hub-kubeconfig:Z \
30+
{% endif %}
31+
{{ eco_gotests_image }}:{{ eco_gotests_tag }} \
32+
--timeout={{ test_timeout }} \
33+
--keep-going \
34+
--output-dir=/tmp/reports \
35+
--junit-report=ginkgo_junit.xml
36+
{%- endmacro %}
37+
38+
{% for feat_config in _eco_gotests_feature_configs | default([]) | selectattr('name', 'in', eco_gotests_features) %}
39+
echo "=== Running {{ feat_config.name }} ==="
40+
rm -rf /tmp/eco_gotests_{{ feat_config.name }}_0/report
41+
mkdir -p /tmp/eco_gotests_{{ feat_config.name }}_0/report
42+
{{ podman_run(feat_config.name, '/tmp/eco_gotests_' ~ feat_config.name ~ '_0/report', feat_config.additional_test_env_variables | default('')) }} || true
43+
44+
{% endfor %}
45+
{% for cycle in ptp_cycle_configs %}
46+
echo "=== PTP Cycle {{ loop.index }}: {{ cycle.name }} ==="
47+
KUBECONFIG={{ spoke_kubeconfig }} oc -n openshift-ptp delete --all ptpconfigs
48+
49+
{% for url in cycle.urls %}
50+
echo "Applying {{ url }}..."
51+
KUBECONFIG={{ spoke_kubeconfig }} oc apply -f {{ url }}
52+
{% endfor %}
53+
54+
echo "Waiting 5 minutes for PTP to stabilize"
55+
sleep 5m
56+
57+
rm -rf {{ eco_gotest_base_dir }}_{{ loop.index }}/report
58+
mkdir -p {{ eco_gotest_base_dir }}_{{ loop.index }}/report
59+
{{ podman_run('ptp', eco_gotest_base_dir ~ '_' ~ loop.index ~ '/report', additional_test_env_variables | default('')) }} || true
60+
61+
{% endfor %}

0 commit comments

Comments
 (0)