|
| 1 | +--- |
| 2 | +# Compare generated hub lockdown with input lockdown |
| 3 | +# |
| 4 | +# This playbook compares two hub lockdown JSON files and reports differences. |
| 5 | +# Used for validation when GENERATE_HUB_LOCKDOWN is enabled along with HUB_LOCKDOWN_URI. |
| 6 | +# |
| 7 | +# Usage: |
| 8 | +# ansible-playbook playbooks/telco-kpis/compare-hub-lockdown.yml \ |
| 9 | +# -i inventories/ocp-deployment/build-inventory.py \ |
| 10 | +# --extra-vars "generated_lockdown=/path/to/generated.json input_lockdown_uri=https://..." |
| 11 | + |
| 12 | +- name: Compare Hub Lockdown Files |
| 13 | + hosts: bastion |
| 14 | + gather_facts: false |
| 15 | + |
| 16 | + vars: |
| 17 | + comparison_output: "/tmp/lockdown-comparison.txt" |
| 18 | + |
| 19 | + tasks: |
| 20 | + - name: Validate required variables |
| 21 | + ansible.builtin.assert: |
| 22 | + that: |
| 23 | + - generated_lockdown is defined |
| 24 | + - input_lockdown_uri is defined |
| 25 | + fail_msg: "Required variables: generated_lockdown, input_lockdown_uri" |
| 26 | + |
| 27 | + - name: Resolve GitLab symlinks and download input lockdown JSON |
| 28 | + ansible.builtin.include_role: |
| 29 | + name: lockdown_hub_config |
| 30 | + tasks_from: resolve_gitlab_symlinks.yml |
| 31 | + vars: |
| 32 | + lockdown_url: "{{ input_lockdown_uri }}" |
| 33 | + lockdown_dest: /tmp/input-lockdown.json |
| 34 | + |
| 35 | + - name: Check if generated lockdown exists |
| 36 | + ansible.builtin.stat: |
| 37 | + path: "{{ generated_lockdown }}" |
| 38 | + register: generated_stat |
| 39 | + |
| 40 | + - name: Fail if generated lockdown not found |
| 41 | + ansible.builtin.fail: |
| 42 | + msg: "Generated lockdown file not found: {{ generated_lockdown }}" |
| 43 | + when: not generated_stat.stat.exists |
| 44 | + |
| 45 | + - name: Compare lockdown files using jd (JSON diff) |
| 46 | + ansible.builtin.shell: | |
| 47 | + set -o pipefail |
| 48 | +
|
| 49 | + # Try jd first (better JSON diff tool) |
| 50 | + if command -v jd &>/dev/null; then |
| 51 | + jd -set /tmp/input-lockdown.json {{ generated_lockdown }} |
| 52 | + else |
| 53 | + # Fallback to jq diff |
| 54 | + echo "=== Input Lockdown (from {{ input_lockdown_uri }}) ===" |
| 55 | + jq -S . /tmp/input-lockdown.json |
| 56 | + echo "" |
| 57 | + echo "=== Generated Lockdown ===" |
| 58 | + jq -S . {{ generated_lockdown }} |
| 59 | + echo "" |
| 60 | + echo "=== Differences (- input, + generated) ===" |
| 61 | + diff -u <(jq -S . /tmp/input-lockdown.json) <(jq -S . {{ generated_lockdown }}) || true |
| 62 | + fi |
| 63 | + args: |
| 64 | + executable: /bin/bash |
| 65 | + register: lockdown_diff |
| 66 | + changed_when: false |
| 67 | + failed_when: false |
| 68 | + |
| 69 | + - name: Save comparison output |
| 70 | + ansible.builtin.copy: |
| 71 | + content: "{{ lockdown_diff.stdout }}" |
| 72 | + dest: "{{ comparison_output }}" |
| 73 | + mode: '0644' |
| 74 | + |
| 75 | + - name: Normalize and checksum input lockdown (excluding metadata) |
| 76 | + ansible.builtin.command: |
| 77 | + cmd: jq -S 'del(.hub.metadata)' /tmp/input-lockdown.json |
| 78 | + register: input_normalized |
| 79 | + changed_when: false |
| 80 | + |
| 81 | + - name: Normalize and checksum generated lockdown (excluding metadata) |
| 82 | + ansible.builtin.command: |
| 83 | + cmd: jq -S 'del(.hub.metadata)' {{ generated_lockdown }} |
| 84 | + register: generated_normalized |
| 85 | + changed_when: false |
| 86 | + |
| 87 | + - name: Set lockdown match result based on normalized content |
| 88 | + ansible.builtin.set_fact: |
| 89 | + lockdown_match: |
| 90 | + rc: "{{ 0 if input_normalized.stdout == generated_normalized.stdout else 1 }}" |
| 91 | + |
| 92 | + - name: Display comparison results |
| 93 | + ansible.builtin.debug: |
| 94 | + msg: |
| 95 | + - "==========================================" |
| 96 | + - "Hub Lockdown Comparison" |
| 97 | + - "==========================================" |
| 98 | + - "Input Lockdown: {{ input_lockdown_uri }}" |
| 99 | + - "Generated Lockdown: {{ generated_lockdown }}" |
| 100 | + - "Match Status: {{ 'IDENTICAL ✓' if lockdown_match.rc == 0 else 'DIFFERENT ⚠' }}" |
| 101 | + - "==========================================" |
| 102 | + |
| 103 | + - name: Display diff output |
| 104 | + ansible.builtin.debug: |
| 105 | + msg: "{{ lockdown_diff.stdout_lines }}" |
| 106 | + when: lockdown_match.rc != 0 |
| 107 | + |
| 108 | + - name: Warn if lockdowns don't match |
| 109 | + ansible.builtin.debug: |
| 110 | + msg: |
| 111 | + - "⚠⚠⚠ WARNING ⚠⚠⚠" |
| 112 | + - "Generated lockdown differs from input lockdown!" |
| 113 | + - "This may indicate:" |
| 114 | + - " - Operator versions were upgraded automatically" |
| 115 | + - " - CatalogSource digests changed" |
| 116 | + - " - Different operator configuration was deployed" |
| 117 | + - "" |
| 118 | + - "Review the diff above to understand the differences." |
| 119 | + - "Consider updating the input lockdown JSON if the generated version is correct." |
| 120 | + when: lockdown_match.rc != 0 |
| 121 | + |
| 122 | + - name: Copy comparison output to artifacts (only when ARTIFACT_DIR is explicitly set) |
| 123 | + when: |
| 124 | + - lockdown_match.rc != 0 |
| 125 | + - lookup('env', 'ARTIFACT_DIR') | length > 0 |
| 126 | + block: |
| 127 | + - name: Ensure artifacts directory exists |
| 128 | + ansible.builtin.file: |
| 129 | + path: "{{ lookup('env', 'ARTIFACT_DIR') }}" |
| 130 | + state: directory |
| 131 | + mode: '0755' |
| 132 | + |
| 133 | + - name: Copy comparison output to artifacts |
| 134 | + ansible.builtin.copy: |
| 135 | + src: "{{ comparison_output }}" |
| 136 | + dest: "{{ lookup('env', 'ARTIFACT_DIR') }}/lockdown-comparison.txt" |
| 137 | + mode: '0644' |
| 138 | + remote_src: true |
0 commit comments