diff --git a/files/ansible-playbooks/sot-updater.yml b/files/ansible-playbooks/sot-updater.yml index ecb0fa4..d319e08 100644 --- a/files/ansible-playbooks/sot-updater.yml +++ b/files/ansible-playbooks/sot-updater.yml @@ -80,37 +80,56 @@ - "raw stdout (joined): {{ nb_preflight.stdout | default('') | trim }}" - # --- Parse the OK line robustly (line-by-line) --- - - name: "NB preflight | Parse OK line (robust)" + # --- Parse the OK line robustly (token-based) --- + - name: "NB preflight | Parse OK line (token)" + when: nb_script.stat.exists + delegate_to: localhost + vars: + nb_lines: >- + {{ (nb_preflight.stdout | default('') | regex_replace('\r','')) | split('\n') | map('trim') | list }} + nb_ok_line: >- + {{ (nb_lines | select('match', '^OK\\s+') | list | last | default('')) }} + nb_tokens: >- + {{ (nb_ok_line | regex_replace('^OK\\s+', '')).split() }} + nb_kv: >- + {{ + dict( + nb_tokens + | select('match', '^[a-zA-Z_]+=') + | map('split', '=', 1) + | map('list') + ) + }} + set_fact: + nb_ok: "{{ (nb_preflight.rc | default(1)) == 0 and (nb_ok_line | length) > 0 }}" + nb_dev: "{{ (nb_tokens | first | default('')) if (nb_tokens|length>0) else '' }}" + nb_ip: "{{ nb_kv.get('ip', '') }}" + nb_fw: "{{ nb_kv.get('fw', '') }}" + nb_node: "{{ nb_kv.get('node', '') }}" + nb_sector: "{{ nb_kv.get('sector', '') }}" + nb_small: "{{ nb_kv.get('small', '') }}" + nb_ok_line: "{{ nb_ok_line }}" + + # --- Detect "cloud vs NetBox (before update) was different" + # Match any of the script's change-indicator lines: + # - "IP: moving ..." + # - "IP: create new ..." + # - "IP: pruning stale ..." + - name: "NB preflight | Detect whether IP changed (pre-update)" when: nb_script.stat.exists delegate_to: localhost vars: nb_lines: >- {{ (nb_preflight.stdout | default('') | regex_replace('\r','')) | split('\n') | map('trim') | list }} - nb_ok_line: >- - {{ (nb_lines | select('match', '^OK\\s+') | list | last | default('')) }} - nb_groups: >- - {{ (nb_ok_line | regex_findall('^OK\\s+(\\S+)\\s+ip=([^\\s]+)\\s+fw=([^\\s]+)\\s+node=([^\\s]+)\\s+sector=([^\\s]+)\\s+small=([^\\s]+)')) | first | default([]) }} + change_lines: >- + {{ + nb_lines + | select('match', '^IP:\\s+(moving|create new|pruning stale)\\b') + | list + }} set_fact: - nb_ok: "{{ (nb_preflight.rc | default(1)) == 0 and (nb_groups | length) == 6 }}" - nb_dev: "{{ nb_groups[0] | default('') }}" - nb_ip: "{{ nb_groups[1] | default('') }}" - nb_fw: "{{ nb_groups[2] | default('') }}" - nb_node: "{{ nb_groups[3] | default('') }}" - nb_sector: "{{ nb_groups[4] | default('') }}" - nb_small: "{{ nb_groups[5] | default('') }}" - nb_ok_line: "{{ nb_ok_line }}" - - # --- Detect "was different before update" via the script's own signal line --- - - name: "NB preflight | Detect whether IP changed (cloud vs prior NetBox)" - when: nb_script.stat.exists - delegate_to: localhost - vars: - nb_lines: >- - {{ (nb_preflight.stdout | default('') | regex_replace('\r','')) | split('\n') | map('trim') | list }} - set_fact: - nb_ip_changed: "{{ (nb_lines | select('match', '^IP:\\s+moving\\s+[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+\\s+from\\s+iface=') | list | length) > 0 }}" - + nb_ip_changed: "{{ (change_lines | length) > 0 }}" + nb_change_lines: "{{ change_lines }}" - name: "NB preflight | Verdict" when: nb_script.stat.exists @@ -118,9 +137,11 @@ ansible.builtin.debug: msg: - "NB preflight verdict: {{ 'IP CHANGED (will requeue)' if nb_ip_changed else 'IP SAME (continue)' }}" + - "Change lines matched: {{ (nb_change_lines | default([])) | join(' | ') if nb_ip_changed else '' }}" - "OK line: {{ nb_ok_line | default('') }}" - "Parsed nb_ip={{ nb_ip | default('') }}" + # --- If IP changed → publish a 3s delayed 'sot-updater' task and stop this host --- - name: "NB preflight | Publish delayed requeue (3s) and stop" when: