1359
This commit is contained in:
@@ -1,18 +1,7 @@
|
|||||||
# ptsd_reacquire_attempt.yml — DHCP reacquire verification + CASE A cleanup (standalone)
|
# ptsd_reacquire_attempt.yml
|
||||||
# Purpose:
|
# PTSD DHCP Reacquire Attempt | Phase 0 | Connectivity + wrapper + DHCP state check + case A cleanup
|
||||||
# 1) Re-run Phase 0 connectivity to DEV2 (same logic as main playbook)
|
|
||||||
# 2) Verify migrated DHCP state:
|
|
||||||
# - ppp0 is absent
|
|
||||||
# - eth0.4000 exists AND has IPv4
|
|
||||||
# 3) If CASE A confirmed (DHCP ok, no PPP), perform minimal cleanup step:
|
|
||||||
# - detect pending reboot process; if found, kill it
|
|
||||||
# Maintain cumulative cleanup report and print at end.
|
|
||||||
#
|
|
||||||
# Notes:
|
|
||||||
# - Does NOT respect /tmp/ptsd.inprogress (verification runs while migration is in progress).
|
|
||||||
# - Does NOT do DEV1 teardown cleanup here (no tunnel/IP removal); this is intentional.
|
|
||||||
|
|
||||||
- name: "PTSD DHCP Reacquire Attempt | Phase 0 | Connectivity + wrapper + DHCP state check + CASE A cleanup"
|
- name: "PTSD DHCP Reacquire Attempt | Phase 0 | Connectivity + wrapper + DHCP state check"
|
||||||
hosts: all
|
hosts: all
|
||||||
gather_facts: no
|
gather_facts: no
|
||||||
|
|
||||||
@@ -72,7 +61,6 @@
|
|||||||
((dev1_host_read.stdout | trim) != (inventory_hostname | string))
|
((dev1_host_read.stdout | trim) != (inventory_hostname | string))
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
# ============================ PHASE 0: LLDP DISCOVERY (IPv4 + IPv6) ============================
|
|
||||||
- name: Compute hostname digits key for LLDP lookup (DEV2)
|
- name: Compute hostname digits key for LLDP lookup (DEV2)
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
dev2_lldp_digits: "{{ (inventory_hostname | string) | regex_replace('[^0-9]', '') }}"
|
dev2_lldp_digits: "{{ (inventory_hostname | string) | regex_replace('[^0-9]', '') }}"
|
||||||
@@ -132,7 +120,6 @@
|
|||||||
- "LLDP IPv4 class={{ lldp_ip_class | default('none') }}"
|
- "LLDP IPv4 class={{ lldp_ip_class | default('none') }}"
|
||||||
- "LLDP IPv6 candidate={{ lldp_dev2_ip6 | default('<none>') }}"
|
- "LLDP IPv6 candidate={{ lldp_dev2_ip6 | default('<none>') }}"
|
||||||
|
|
||||||
# ============================ PHASE 0: PRIMARY PATH DECISION ============================
|
|
||||||
- name: Override dev2_host from LLDP when candidate is 192.168.x.x
|
- name: Override dev2_host from LLDP when candidate is 192.168.x.x
|
||||||
when: (lldp_ip_class | trim) == "192_168" and (lldp_dev2_ip | trim | length > 0)
|
when: (lldp_ip_class | trim) == "192_168" and (lldp_dev2_ip | trim | length > 0)
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
@@ -146,7 +133,6 @@
|
|||||||
dev2_conn_method: "{{ 'direct_lldp' if ((lldp_ip_class | trim) == '10') else 'tunnel' }}"
|
dev2_conn_method: "{{ 'direct_lldp' if ((lldp_ip_class | trim) == '10') else 'tunnel' }}"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
# ============================ PHASE 0: DIRECT LLDP IPv4 AUTH (10.x) ============================
|
|
||||||
- name: Try DEV2 login via direct LLDP IPv4 (10.x) with basicpass
|
- name: Try DEV2 login via direct LLDP IPv4 (10.x) with basicpass
|
||||||
when: dev2_conn_method == "direct_lldp"
|
when: dev2_conn_method == "direct_lldp"
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
@@ -189,7 +175,6 @@
|
|||||||
dev2_passfile_used_direct: "basicpass2"
|
dev2_passfile_used_direct: "basicpass2"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
# ============================ PHASE 0: TUNNEL PREP (DEV1 temp IP + ARP + tunnel) ============================
|
|
||||||
- name: Add temporary IP on DEV1 (tolerate 'File exists')
|
- name: Add temporary IP on DEV1 (tolerate 'File exists')
|
||||||
when: dev2_conn_method == "tunnel"
|
when: dev2_conn_method == "tunnel"
|
||||||
ansible.builtin.raw: >
|
ansible.builtin.raw: >
|
||||||
@@ -291,7 +276,7 @@
|
|||||||
_ctrl_sock: "{{ (mktemp_dir.stdout | trim) }}/ssh_tunnel_ctl"
|
_ctrl_sock: "{{ (mktemp_dir.stdout | trim) }}/ssh_tunnel_ctl"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Start SSH ControlMaster and forward 127.0.0.1:local_port → DEV2:22 via DEV1
|
- name: Start SSH ControlMaster and forward 127.0.0.1:local_port to DEV2 22 via DEV1
|
||||||
when: dev2_conn_method == "tunnel"
|
when: dev2_conn_method == "tunnel"
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.shell: |
|
ansible.builtin.shell: |
|
||||||
@@ -363,145 +348,6 @@
|
|||||||
dev2_passfile_used_tunnel: "basicpass2"
|
dev2_passfile_used_tunnel: "basicpass2"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
# ============================ PHASE 0: SAFETY GUARD (MAC CHECK) ============================
|
|
||||||
- name: Read remote eth0 MAC via tunnel (guard, sanitized)
|
|
||||||
when:
|
|
||||||
- dev2_conn_method == "tunnel"
|
|
||||||
- (dev2_passfile_used_tunnel | default('NONE')) != "NONE"
|
|
||||||
- (dev2_mac | default('') | length) > 0
|
|
||||||
delegate_to: localhost
|
|
||||||
ansible.builtin.shell: |
|
|
||||||
PORT="{{ _local_port }}"
|
|
||||||
sshpass -f "{{ dev2_passfile_used_tunnel }}" ssh {{ ssh_opts_common }} \
|
|
||||||
-p "$PORT" "{{ dev2_ssh_user }}@127.0.0.1" \
|
|
||||||
"cat /sys/class/net/eth0/address 2>/dev/null || ip link show eth0 2>/dev/null" 2>&1
|
|
||||||
args: { executable: /bin/bash }
|
|
||||||
register: dev2_eth0_mac_raw
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: Normalize remote eth0 MAC (extract last MAC-like token)
|
|
||||||
when:
|
|
||||||
- dev2_conn_method == "tunnel"
|
|
||||||
- (dev2_passfile_used_tunnel | default('NONE')) != "NONE"
|
|
||||||
- (dev2_mac | default('') | length) > 0
|
|
||||||
delegate_to: localhost
|
|
||||||
ansible.builtin.set_fact:
|
|
||||||
remote_eth0_mac: >-
|
|
||||||
{{
|
|
||||||
(
|
|
||||||
(dev2_eth0_mac_raw.stdout | default('') | regex_replace('\r','')) ~ "\n" ~
|
|
||||||
(dev2_eth0_mac_raw.stderr | default('') | regex_replace('\r',''))
|
|
||||||
)
|
|
||||||
| regex_findall('([0-9a-fA-F]{2}(?::[0-9a-fA-F]{2}){5})')
|
|
||||||
| last
|
|
||||||
| default('')
|
|
||||||
| lower
|
|
||||||
}}
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Abort if remote eth0 MAC != discovered DEV2 MAC
|
|
||||||
when:
|
|
||||||
- dev2_conn_method == "tunnel"
|
|
||||||
- (dev2_passfile_used_tunnel | default('NONE')) != "NONE"
|
|
||||||
- (dev2_mac | default('') | length) > 0
|
|
||||||
- (remote_eth0_mac | default('') | length) > 0
|
|
||||||
- (remote_eth0_mac | lower) != (dev2_mac | lower)
|
|
||||||
ansible.builtin.fail:
|
|
||||||
msg: >-
|
|
||||||
Safety stop: tunnel reached wrong device.
|
|
||||||
expected_dev2_mac={{ dev2_mac }}, remote_eth0_mac={{ remote_eth0_mac }}
|
|
||||||
|
|
||||||
# ============================ PHASE 0: FALLBACKS (only if tunnel auth failed) ============================
|
|
||||||
- name: Try DEV2 login via LLDP IPv4 10.x (fallback if tunnel auth failed)
|
|
||||||
when:
|
|
||||||
- dev2_conn_method == "tunnel"
|
|
||||||
- dev2_passfile_used_tunnel == "NONE"
|
|
||||||
- (lldp_dev2_ip | default('')) is match('^10\\.')
|
|
||||||
delegate_to: localhost
|
|
||||||
ansible.builtin.shell: |
|
|
||||||
set -e
|
|
||||||
HOST="{{ lldp_dev2_ip }}"
|
|
||||||
for f in {{ dev2_passfiles | join(' ') }}; do
|
|
||||||
if timeout 20s sshpass -f "$f" ssh {{ ssh_opts_common }} \
|
|
||||||
-o AddressFamily=inet \
|
|
||||||
-o ConnectTimeout=10 \
|
|
||||||
"{{ dev2_ssh_user }}@${HOST}" echo OK >/dev/null 2>&1; then
|
|
||||||
echo "$f"; exit 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo "NONE"; exit 1
|
|
||||||
args: { executable: /bin/bash }
|
|
||||||
register: dev2_auth_lldp4
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Record LLDP IPv4 fallback decision
|
|
||||||
when:
|
|
||||||
- dev2_conn_method == "tunnel"
|
|
||||||
- dev2_passfile_used_tunnel == "NONE"
|
|
||||||
- (lldp_dev2_ip | default('')) is match('^10\\.')
|
|
||||||
delegate_to: localhost
|
|
||||||
ansible.builtin.set_fact:
|
|
||||||
dev2_passfile_used_lldp4: "{{ (dev2_auth_lldp4.rc == 0) | ternary((dev2_auth_lldp4.stdout | trim), 'NONE') }}"
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Copy DEV2 passfiles to DEV1 for IPv6 nested SSH (last resort)
|
|
||||||
when:
|
|
||||||
- dev2_conn_method == "tunnel"
|
|
||||||
- dev2_passfile_used_tunnel == "NONE"
|
|
||||||
- dev2_passfile_used_lldp4 == "NONE"
|
|
||||||
- (lldp_dev2_ip6 | default('') | length) > 0
|
|
||||||
ansible.builtin.copy:
|
|
||||||
src: "{{ item }}"
|
|
||||||
dest: "/tmp/{{ item }}"
|
|
||||||
mode: "0600"
|
|
||||||
loop: "{{ dev2_passfiles }}"
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Try DEV2 login via LLDP IPv6 (nested SSH through DEV1; last resort)
|
|
||||||
when:
|
|
||||||
- dev2_conn_method == "tunnel"
|
|
||||||
- dev2_passfile_used_tunnel == "NONE"
|
|
||||||
- dev2_passfile_used_lldp4 == "NONE"
|
|
||||||
- (lldp_dev2_ip6 | default('') | length) > 0
|
|
||||||
delegate_to: localhost
|
|
||||||
ansible.builtin.shell: |
|
|
||||||
set -e
|
|
||||||
IP6="{{ lldp_dev2_ip6 }}"
|
|
||||||
for f in {{ dev2_passfiles | join(' ') }}; do
|
|
||||||
if sshpass -p '{{ dev1_pass }}' ssh {{ ssh_opts_common }} \
|
|
||||||
"{{ dev1_user }}@{{ ansible_host|default(inventory_hostname) }}" \
|
|
||||||
"timeout {{ ssh_timeout }}s sshpass -f '/tmp/${f}' ssh \
|
|
||||||
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR \
|
|
||||||
-o PubkeyAuthentication=no \
|
|
||||||
-o PreferredAuthentications=password -o NumberOfPasswordPrompts=1 \
|
|
||||||
-o ConnectTimeout={{ ssh_timeout }} \
|
|
||||||
'{{ dev2_ssh_user }}@\[${IP6}%{{ dev1_iface }}\]' 'echo OK' " \
|
|
||||||
>/dev/null 2>&1; then
|
|
||||||
echo "$f"; exit 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo "NONE"; exit 1
|
|
||||||
args: { executable: /bin/bash }
|
|
||||||
register: dev2_auth_lldp6
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Record LLDP IPv6 fallback decision
|
|
||||||
when:
|
|
||||||
- dev2_conn_method == "tunnel"
|
|
||||||
- dev2_passfile_used_tunnel == "NONE"
|
|
||||||
- dev2_passfile_used_lldp4 == "NONE"
|
|
||||||
- (lldp_dev2_ip6 | default('') | length) > 0
|
|
||||||
delegate_to: localhost
|
|
||||||
ansible.builtin.set_fact:
|
|
||||||
dev2_passfile_used_lldp6: "{{ (dev2_auth_lldp6.rc == 0) | ternary((dev2_auth_lldp6.stdout | trim), 'NONE') }}"
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
# ============================ PHASE 0: FINAL DECISION + WRAPPER FACTS ============================
|
|
||||||
- name: Decide final DEV2 connection mode (direct_lldp > tunnel > lldp4 > lldp6)
|
- name: Decide final DEV2 connection mode (direct_lldp > tunnel > lldp4 > lldp6)
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
@@ -510,10 +356,6 @@
|
|||||||
direct_lldp
|
direct_lldp
|
||||||
{%- elif dev2_conn_method == 'tunnel' and (dev2_passfile_used_tunnel | default('NONE')) != 'NONE' -%}
|
{%- elif dev2_conn_method == 'tunnel' and (dev2_passfile_used_tunnel | default('NONE')) != 'NONE' -%}
|
||||||
tunnel
|
tunnel
|
||||||
{%- elif (dev2_passfile_used_lldp4 | default('NONE')) != 'NONE' -%}
|
|
||||||
lldp4_fallback
|
|
||||||
{%- elif (dev2_passfile_used_lldp6 | default('NONE')) != 'NONE' -%}
|
|
||||||
lldp6_via_dev1
|
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
none
|
none
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
@@ -523,10 +365,9 @@
|
|||||||
when: dev2_conn_final == "none"
|
when: dev2_conn_final == "none"
|
||||||
ansible.builtin.fail:
|
ansible.builtin.fail:
|
||||||
msg: >
|
msg: >
|
||||||
DEV2 unreachable: tunnel auth={{ dev2_passfile_used_tunnel | default('n/a') }},
|
DEV2 unreachable:
|
||||||
direct auth={{ dev2_passfile_used_direct | default('n/a') }},
|
tunnel={{ dev2_passfile_used_tunnel | default('n/a') }},
|
||||||
lldp4 auth={{ dev2_passfile_used_lldp4 | default('n/a') }},
|
direct={{ dev2_passfile_used_direct | default('n/a') }}.
|
||||||
lldp6 auth={{ dev2_passfile_used_lldp6 | default('n/a') }}.
|
|
||||||
|
|
||||||
- name: Debug final connectivity decision
|
- name: Debug final connectivity decision
|
||||||
when: debugging | bool
|
when: debugging | bool
|
||||||
@@ -536,9 +377,7 @@
|
|||||||
- "dev2_conn_final={{ dev2_conn_final }}"
|
- "dev2_conn_final={{ dev2_conn_final }}"
|
||||||
- "tunnel passfile={{ dev2_passfile_used_tunnel | default('n/a') }}"
|
- "tunnel passfile={{ dev2_passfile_used_tunnel | default('n/a') }}"
|
||||||
- "direct passfile={{ dev2_passfile_used_direct | default('n/a') }}"
|
- "direct passfile={{ dev2_passfile_used_direct | default('n/a') }}"
|
||||||
- "lldp4 passfile={{ dev2_passfile_used_lldp4 | default('n/a') }}"
|
- "tunnel target={{ dev2_host }}:{{ dev2_port }} forwarded 127.0.0.1:{{ _local_port | default('na') }}"
|
||||||
- "lldp6 passfile={{ dev2_passfile_used_lldp6 | default('n/a') }}"
|
|
||||||
- "tunnel target={{ dev2_host }}:{{ dev2_port }} (forwarded to 127.0.0.1:{{ _local_port | default('na') }})"
|
|
||||||
- "lldp ipv4={{ lldp_dev2_ip | default('') }}"
|
- "lldp ipv4={{ lldp_dev2_ip | default('') }}"
|
||||||
- "lldp ipv6={{ lldp_dev2_ip6 | default('') }}"
|
- "lldp ipv6={{ lldp_dev2_ip6 | default('') }}"
|
||||||
|
|
||||||
@@ -549,7 +388,7 @@
|
|||||||
set -e
|
set -e
|
||||||
MODE="{{ dev2_conn_final }}"
|
MODE="{{ dev2_conn_final }}"
|
||||||
if [ -z "${DEV2_CMD:-}" ]; then
|
if [ -z "${DEV2_CMD:-}" ]; then
|
||||||
echo "ERROR: DEV2_CMD is empty" >&2
|
echo "ERROR DEV2_CMD empty" >&2
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -570,82 +409,60 @@
|
|||||||
"{{ dev2_ssh_user }}@${HOST}" \
|
"{{ dev2_ssh_user }}@${HOST}" \
|
||||||
"{{ pathprefix }} ${DEV2_CMD}" 2>&1
|
"{{ pathprefix }} ${DEV2_CMD}" 2>&1
|
||||||
;;
|
;;
|
||||||
lldp4_fallback)
|
|
||||||
HOST="{{ lldp_dev2_ip }}"
|
|
||||||
PASS="{{ dev2_passfile_used_lldp4 }}"
|
|
||||||
sshpass -f "$PASS" ssh {{ ssh_opts_common }} \
|
|
||||||
-o AddressFamily=inet \
|
|
||||||
"{{ dev2_ssh_user }}@${HOST}" \
|
|
||||||
"{{ pathprefix }} ${DEV2_CMD}" 2>&1
|
|
||||||
;;
|
|
||||||
lldp6_via_dev1)
|
|
||||||
IP6="{{ lldp_dev2_ip6 }}"
|
|
||||||
F="{{ dev2_passfile_used_lldp6 }}"
|
|
||||||
sshpass -p "{{ dev1_pass }}" ssh {{ ssh_opts_common }} \
|
|
||||||
"{{ dev1_user }}@{{ ansible_host | default(inventory_hostname) }}" \
|
|
||||||
"sshpass -f '/tmp/${F}' ssh \
|
|
||||||
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR \
|
|
||||||
-o PubkeyAuthentication=no \
|
|
||||||
-o PreferredAuthentications=password -o NumberOfPasswordPrompts=1 \
|
|
||||||
-o ConnectTimeout={{ ssh_timeout }} \
|
|
||||||
'{{ dev2_ssh_user }}@\[${IP6}%{{ dev1_iface }}\]' \
|
|
||||||
'{{ pathprefix }} '"${DEV2_CMD}" 2>&1"
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
echo "ERROR: unknown MODE=$MODE" >&2
|
echo "ERROR unknown MODE=$MODE" >&2
|
||||||
exit 3
|
exit 3
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
# ============================ VERIFY: DHCP MIGRATION STATE ============================
|
- name: VERIFY DEV2 check ppp0 exists?
|
||||||
- name: VERIFY | DEV2 check ppp0 exists?
|
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.shell: |
|
ansible.builtin.shell: |
|
||||||
export DEV2_CMD="ip link show ppp0 >/dev/null 2>&1 && echo YES || echo NO"
|
export DEV2_CMD="ip link show ppp0 >/dev/null 2>&1 && echo YES || echo NO"
|
||||||
{{ dev2_exec_cmd }}
|
{{ dev2_exec_cmd }}
|
||||||
args: { executable: /bin/bash }
|
args: { executable: /bin/bash }
|
||||||
register: v_ppp0_exists
|
register: dev2_ppp0_exists
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: VERIFY | DEV2 check eth0.4000 exists?
|
- name: VERIFY DEV2 check eth0.4000 exists?
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.shell: |
|
ansible.builtin.shell: |
|
||||||
export DEV2_CMD="ip link show eth0.4000 >/dev/null 2>&1 && echo YES || echo NO"
|
export DEV2_CMD="ip link show eth0.4000 >/dev/null 2>&1 && echo YES || echo NO"
|
||||||
{{ dev2_exec_cmd }}
|
{{ dev2_exec_cmd }}
|
||||||
args: { executable: /bin/bash }
|
args: { executable: /bin/bash }
|
||||||
register: v_eth04000_exists
|
register: dev2_eth04000_exists
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: VERIFY | DEV2 check eth0.4000 has IPv4?
|
- name: VERIFY DEV2 check eth0.4000 has IPv4?
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.shell: |
|
ansible.builtin.shell: |
|
||||||
export DEV2_CMD="ip -4 addr show dev eth0.4000 2>/dev/null | grep -m1 'inet ' >/dev/null 2>&1 && echo YES || echo NO"
|
export DEV2_CMD="ip -4 addr show dev eth0.4000 2>/dev/null | grep -m1 'inet ' >/dev/null 2>&1 && echo YES || echo NO"
|
||||||
{{ dev2_exec_cmd }}
|
{{ dev2_exec_cmd }}
|
||||||
args: { executable: /bin/bash }
|
args: { executable: /bin/bash }
|
||||||
register: v_eth04000_has_ipv4
|
register: dev2_eth04000_has_ipv4
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: VERIFY | Summarize DHCP migration state
|
- name: VERIFY Summarize DHCP migration state
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
ppp0_exists: "{{ (v_ppp0_exists.stdout | default('') | trim) == 'YES' }}"
|
ppp0_exists: "{{ (dev2_ppp0_exists.stdout | default('') | trim) == 'YES' }}"
|
||||||
eth04000_exists: "{{ (v_eth04000_exists.stdout | default('') | trim) == 'YES' }}"
|
eth04000_exists: "{{ (dev2_eth04000_exists.stdout | default('') | trim) == 'YES' }}"
|
||||||
eth04000_has_ipv4: "{{ (v_eth04000_has_ipv4.stdout | default('') | trim) == 'YES' }}"
|
eth04000_has_ipv4: "{{ (dev2_eth04000_has_ipv4.stdout | default('') | trim) == 'YES' }}"
|
||||||
dhcp_migrated_ok: >-
|
dhcp_migrated_ok: >-
|
||||||
{{
|
{{
|
||||||
((v_ppp0_exists.stdout | default('') | trim) != 'YES')
|
((dev2_ppp0_exists.stdout | default('') | trim) != 'YES')
|
||||||
and
|
and
|
||||||
((v_eth04000_exists.stdout | default('') | trim) == 'YES')
|
((dev2_eth04000_exists.stdout | default('') | trim) == 'YES')
|
||||||
and
|
and
|
||||||
((v_eth04000_has_ipv4.stdout | default('') | trim) == 'YES')
|
((dev2_eth04000_has_ipv4.stdout | default('') | trim) == 'YES')
|
||||||
}}
|
}}
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: VERIFY | Result DHCP migrated (SUCCESS) or not (graceful stop)
|
- name: VERIFY Result DHCP migrated (SUCCESS) or not (graceful stop)
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.debug:
|
ansible.builtin.debug:
|
||||||
msg:
|
msg:
|
||||||
@@ -654,53 +471,50 @@
|
|||||||
- "eth0.4000_exists={{ eth04000_exists }}"
|
- "eth0.4000_exists={{ eth04000_exists }}"
|
||||||
- "eth0.4000_has_ipv4={{ eth04000_has_ipv4 }}"
|
- "eth0.4000_has_ipv4={{ eth04000_has_ipv4 }}"
|
||||||
- "dhcp_migrated_ok={{ dhcp_migrated_ok }}"
|
- "dhcp_migrated_ok={{ dhcp_migrated_ok }}"
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: VERIFY | Graceful stop if DHCP migration state is not confirmed
|
- name: VERIFY Graceful stop if DHCP migration state is not confirmed
|
||||||
when: not (dhcp_migrated_ok | bool)
|
when: not (dhcp_migrated_ok | bool)
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.debug:
|
ansible.builtin.debug:
|
||||||
msg:
|
msg:
|
||||||
- "Graceful stop: DHCP migration state is not confirmed (not CASE A)."
|
- "Graceful stop DHCP state not confirmed"
|
||||||
- "ppp0_exists={{ ppp0_exists }}"
|
- "ppp0_exists={{ ppp0_exists }}"
|
||||||
- "eth0.4000_exists={{ eth04000_exists }}"
|
- "eth0.4000_exists={{ eth04000_exists }}"
|
||||||
- "eth0.4000_has_ipv4={{ eth04000_has_ipv4 }}"
|
- "eth0.4000_has_ipv4={{ eth04000_has_ipv4 }}"
|
||||||
- "dev2_conn_final={{ dev2_conn_final }}"
|
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: VERIFY | End host if DHCP migration state is not confirmed
|
- name: VERIFY End host if DHCP migration state is not confirmed
|
||||||
when: not (dhcp_migrated_ok | bool)
|
when: not (dhcp_migrated_ok | bool)
|
||||||
ansible.builtin.meta: end_host
|
ansible.builtin.meta: end_host
|
||||||
|
|
||||||
# ============================ CASE A CLEANUP (DHCP OK, NO PPP) ============================
|
|
||||||
|
|
||||||
- name: CASE A Initialize cumulative cleanup report
|
- name: CASE A Initialize cumulative cleanup report
|
||||||
when: dhcp_migrated_ok | bool
|
when: dhcp_migrated_ok | bool
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
case_a_report: "case A observed"
|
cleanup_report: "case A observed"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: CASE A DEV2 detect pending reboot process
|
- name: CASE A DEV2 cancel pending reboot if present
|
||||||
when: dhcp_migrated_ok | bool
|
when: dhcp_migrated_ok | bool
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.shell: |
|
ansible.builtin.shell: |
|
||||||
export DEV2_CMD="ps w | grep eboot | grep -v grep >/dev/null 2>&1 && echo YES || echo NO"
|
set -e
|
||||||
|
export DEV2_CMD="ps w | grep eboot | grep -v grep >/dev/null 2>&1 && echo FOUND || echo NOT_FOUND"
|
||||||
{{ dev2_exec_cmd }}
|
{{ dev2_exec_cmd }}
|
||||||
args: { executable: /bin/bash }
|
args: { executable: /bin/bash }
|
||||||
register: reboot_detect
|
register: reboot_present
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: CASE A DEV2 cancel pending reboot if found
|
- name: CASE A DEV2 cancel reboot if present
|
||||||
when:
|
when: dhcp_migrated_ok | bool and (reboot_present.stdout | default('') | trim) == "FOUND"
|
||||||
- dhcp_migrated_ok | bool
|
|
||||||
- (reboot_detect.stdout | trim) == "YES"
|
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.shell: |
|
ansible.builtin.shell: |
|
||||||
export DEV2_CMD="killall reboot 2>/dev/null || true"
|
set -e
|
||||||
|
export DEV2_CMD="ps w | grep eboot | grep -v grep >/dev/null 2>&1 && killall reboot 2>/dev/null || true; echo DONE"
|
||||||
{{ dev2_exec_cmd }}
|
{{ dev2_exec_cmd }}
|
||||||
args: { executable: /bin/bash }
|
args: { executable: /bin/bash }
|
||||||
|
register: reboot_cancel
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
@@ -708,11 +522,16 @@
|
|||||||
when: dhcp_migrated_ok | bool
|
when: dhcp_migrated_ok | bool
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
case_a_report: >-
|
cleanup_report: >-
|
||||||
{{ case_a_report
|
{{
|
||||||
~ '; pending reboot '
|
cleanup_report
|
||||||
~ ((reboot_detect.stdout | trim) == 'YES'
|
~ '; '
|
||||||
| ternary('found and cancelled', 'not found')) }}
|
~ (
|
||||||
|
'pending reboot found and cancelled'
|
||||||
|
if (reboot_present.stdout | default('') | trim) == 'FOUND'
|
||||||
|
else 'no pending reboot'
|
||||||
|
)
|
||||||
|
}}
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: CASE A final cumulative cleanup report
|
- name: CASE A final cumulative cleanup report
|
||||||
@@ -720,6 +539,49 @@
|
|||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.debug:
|
ansible.builtin.debug:
|
||||||
msg:
|
msg:
|
||||||
- "{{ case_a_report }}"
|
- "{{ cleanup_report }}"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
|
post_tasks:
|
||||||
|
- name: Cleanup note
|
||||||
|
delegate_to: localhost
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Cleanup best-effort closing tunnel removing temp IP removing staged passfiles"
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Close SSH ControlMaster (best-effort)
|
||||||
|
when: dev2_conn_method | default('') == "tunnel"
|
||||||
|
delegate_to: localhost
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
ssh -S "{{ _ctrl_sock | default('/dev/null') }}" -O exit 2>/dev/null || true
|
||||||
|
args: { executable: /bin/bash }
|
||||||
|
changed_when: false
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Remove tunnel control dir (best-effort)
|
||||||
|
when: dev2_conn_method | default('') == "tunnel"
|
||||||
|
delegate_to: localhost
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ _ctrl_dir | default('/tmp/none') }}"
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Remove staged passfiles from DEV1 (best-effort)
|
||||||
|
when: dev2_conn_method | default('') == "tunnel"
|
||||||
|
ansible.builtin.raw: >
|
||||||
|
{{ pathprefix }}
|
||||||
|
rm -f /tmp/basicpass /tmp/basicpass2 2>/dev/null || true
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Remove temporary IP on DEV1 (tolerate 'Cannot assign requested address')
|
||||||
|
when: dev2_conn_method | default('') == "tunnel"
|
||||||
|
ansible.builtin.raw: >
|
||||||
|
{{ pathprefix }}
|
||||||
|
ip a del {{ dev2_side_ip }} dev {{ dev1_iface }}
|
||||||
|
register: del_ip
|
||||||
|
changed_when: del_ip.rc == 0
|
||||||
|
failed_when: >
|
||||||
|
del_ip.rc != 0
|
||||||
|
and ('Cannot assign requested address' not in (del_ip.stdout | default('')))
|
||||||
|
and ('Cannot assign requested address' not in (del_ip.stderr | default('')))
|
||||||
|
|||||||
Reference in New Issue
Block a user