Update mikrotikbackup_clean.yml

This commit is contained in:
2026-09-24 17:55:18 +00:00
parent 87150f8cd9
commit 00b56a7c06
+120 -76
View File
@@ -1,151 +1,195 @@
---
- name: Backup and/or Upgrade MikroTik - name: Backup and/or Upgrade MikroTik
hosts: mikrotik_routers hosts: mikrotik_routers
gather_facts: no gather_facts: false
vars: vars:
backup_dir: /opt/mikrotik_backups/ backup_dir: /opt/mikrotik_backups/
ansible_connection: ansible.netcommon.network_cli
ansible_network_os: community.routeros.routeros
ansible_connect_timeout: 60
ansible_command_timeout: 60
upgrade_command_timeout: 600
upgrade_reconnect_timeout: 600
upgrade_verify_retries: 40
upgrade_verify_delay: 15
tasks: tasks:
# ----------------------------
# Always: identity + timestamp
# ----------------------------
- name: Get router identity - name: Get router identity
community.routeros.command: community.routeros.command:
commands: /system identity print commands: /system identity print
register: identity_raw register: identity_raw
changed_when: false
tags: always tags: always
- name: Parse router name - name: Parse router name
set_fact: ansible.builtin.set_fact:
router_name: "{{ identity_raw.stdout[0].split(': ')[1] | trim }}" router_name: "{{ identity_raw.stdout[0].split(': ', 1)[1] | trim }}"
tags: always tags: always
- name: Get timestamp - name: Get timestamp
ansible.builtin.command: date +%Y-%m-%d_%H-%M-%S ansible.builtin.command: date +%Y-%m-%d_%H-%M-%S
register: date_out register: date_out
delegate_to: localhost delegate_to: localhost
vars:
ansible_connection: local
changed_when: false
tags: always tags: always
- name: Set timestamp fact - name: Set timestamp fact
set_fact: ansible.builtin.set_fact:
ts: "{{ date_out.stdout }}" ts: "{{ date_out.stdout }}"
tags: always tags: always
# ---------------------------- - name: Back up router configuration
# Backup (tag: backup) tags: [backup, never]
# ---------------------------- block:
- name: Ensure local backup directory exists - name: Ensure local backup directory exists
ansible.builtin.file: ansible.builtin.file:
path: "{{ backup_dir }}" path: "{{ backup_dir }}"
state: directory state: directory
mode: "0755" mode: "0755"
delegate_to: localhost delegate_to: localhost
tags: [backup, never] vars:
ansible_connection: local
- name: Export router config - name: Export router config
community.routeros.command: community.routeros.command:
commands: /export terse show-sensitive commands: /export terse show-sensitive
register: export_cfg register: export_cfg
tags: [backup, never] changed_when: false
no_log: true
- name: Save export locally - name: Save export locally
ansible.builtin.copy: ansible.builtin.copy:
content: "{{ export_cfg.stdout[0] }}" content: "{{ export_cfg.stdout[0] }}"
dest: "{{ backup_dir }}/{{ router_name }}-{{ ts }}.rsc" dest: "{{ backup_dir }}/{{ router_name }}-{{ ts }}.rsc"
mode: "0600"
delegate_to: localhost delegate_to: localhost
tags: [backup, never] vars:
ansible_connection: local
no_log: true
# ---------------------------- - name: Check and upgrade RouterOS packages
# Upgrade (tag: upgrade) tags: [upgrade, never]
# ---------------------------- when: not ansible_check_mode
block:
- name: Check current and latest available package versions - name: Check current and latest available package versions
community.routeros.command: community.routeros.command:
commands: /system package update check-for-updates commands: /system package update check-for-updates
register: update_check register: update_check
tags: [upgrade, never] changed_when: false
- name: Normalize update output - name: Normalize update output
set_fact: ansible.builtin.set_fact:
_update_text: "{{ update_check.stdout[0] | replace('\r', '') }}" _update_text: "{{ update_check.stdout[0] | replace('\r', '') }}"
tags: [upgrade, never]
- name: Debug raw update output
ansible.builtin.debug:
msg: "{{ _update_text }}"
tags: [upgrade, never]
- name: Parse installed and latest versions - name: Parse installed and latest versions
set_fact: ansible.builtin.set_fact:
installed_version: >- installed_version: >-
{{ {{ (_update_text | regex_findall('(?:installed|current)-version:[ \t]*([0-9][0-9A-Za-z.-]*)')
(_update_text | regex_findall('(?:installed|current)-version:[ ]*([0-9A-Za-z.]+)'))[0] | first) | default('unknown') }}
if (_update_text | regex_findall('(?:installed|current)-version:[ ]*([0-9A-Za-z.]+)'))
else 'unknown'
}}
latest_version: >- latest_version: >-
{{ {{ (_update_text | regex_findall('(?:latest|newest)-version:[ \t]*([0-9][0-9A-Za-z.-]*)')
(_update_text | regex_findall('(?:latest|newest)-version:[ ]*([0-9A-Za-z.]+)'))[0] | first) | default('unknown') }}
if (_update_text | regex_findall('(?:latest|newest)-version:[ ]*([0-9A-Za-z.]+)'))
else 'unknown'
}}
tags: [upgrade, never]
- name: Fail if versions could not be parsed - name: Require valid versions before attempting an upgrade
ansible.builtin.fail: ansible.builtin.assert:
msg: > that:
Could not parse versions from update output. - installed_version != 'unknown'
Raw text was: {{ _update_text }} - latest_version != 'unknown'
when: installed_version == 'unknown' or latest_version == 'unknown' fail_msg: "Could not parse versions from update output: {{ _update_text }}"
tags: [upgrade, never]
- name: Debug parsed versions - name: Show installed and available versions
ansible.builtin.debug: ansible.builtin.debug:
msg: msg: "{{ router_name }}: installed={{ installed_version }}, available={{ latest_version }}"
- "Installed: {{ installed_version }}"
- "Latest: {{ latest_version }}"
tags: [upgrade, never]
- name: Skip upgrade if already on latest - name: Skip upgrade if already on latest
ansible.builtin.debug: ansible.builtin.debug:
msg: "Router {{ router_name }} is already on latest version {{ installed_version }}. Skipping upgrade." msg: "{{ router_name }} is already on {{ installed_version }}. Skipping upgrade."
when: installed_version == latest_version when: installed_version == latest_version
tags: [upgrade, never]
- name: Install and verify the available version
when: installed_version != latest_version
block:
- name: Reset persistent connection before installation
ansible.builtin.meta: reset_connection
- name: Request package installation
block:
- name: Trigger package download and install - name: Trigger package download and install
community.routeros.command: community.routeros.command:
commands: /system package update install commands: /system package update install
vars: vars:
ansible_command_timeout: 60 ansible_command_timeout: "{{ upgrade_command_timeout }}"
when: installed_version != latest_version register: install_result
ignore_errors: true
tags: [upgrade, never]
- name: Wait before reconnecting after reboot rescue:
ansible.builtin.pause: # A reboot can interrupt the command response. This is NOT
seconds: 30 # success: the mandatory version check below decides the result.
when: installed_version != latest_version - name: Record installation error for final verification
tags: [upgrade, never] ansible.builtin.debug:
msg: >-
Installation returned an error: {{ install_result.msg | default('Unknown error') }}.
The command may or may not have reached the router.
Continuing only to verify the actual installed version.
- name: Wait for router to come back online after reboot always:
community.routeros.command: - name: Discard the installation connection
commands: /system resource print ansible.builtin.meta: reset_connection
register: reboot_wait
until: reboot_wait is succeeded
retries: 20
delay: 15
when: installed_version != latest_version
tags: [upgrade, never]
- name: Confirm upgraded version # This readiness check does not claim that a reboot occurred.
# The exact version comparison below is the success criterion.
- name: Wait for SSH availability from Semaphore
ansible.builtin.wait_for:
host: >-
{{ hostvars[inventory_hostname].ansible_host
| default(hostvars[inventory_hostname].ansible_ssh_host)
| default(inventory_hostname) }}
port: >-
{{ hostvars[inventory_hostname].ansible_port
| default(hostvars[inventory_hostname].ansible_ssh_port)
| default(22) }}
state: started
search_regex: SSH-
delay: 30
sleep: 5
connect_timeout: 5
timeout: "{{ upgrade_reconnect_timeout }}"
delegate_to: localhost
vars:
ansible_connection: local
changed_when: false
- name: Reset persistent connection before verification
ansible.builtin.meta: reset_connection
- name: Verify the installed version
block:
- name: Wait until the router reports the expected version
community.routeros.command: community.routeros.command:
commands: /system resource print commands: /system resource print
register: post_upgrade_info register: post_upgrade_info
when: installed_version != latest_version changed_when: false
tags: [upgrade, never] until:
- post_upgrade_info is succeeded
- >-
((post_upgrade_info.stdout | default(['']) | first
| regex_findall('(?m)^\s*version:[ \t]*([0-9][0-9A-Za-z.-]*)')
| first) | default('unknown')) == latest_version
retries: "{{ upgrade_verify_retries }}"
delay: "{{ upgrade_verify_delay }}"
- name: Show post-upgrade RouterOS version rescue:
- name: Fail if the expected RouterOS version could not be verified
ansible.builtin.fail:
msg: >-
Upgrade NOT verified for {{ router_name }}.
Previous={{ installed_version }}; expected={{ latest_version }}.
Last router response={{ post_upgrade_info.stdout | default([]) }}.
Verification error={{ post_upgrade_info.msg | default('Version mismatch') }}.
Install error={{ install_result.msg | default('No module error reported') }}.
- name: Report verified upgrade
ansible.builtin.debug: ansible.builtin.debug:
msg: "{{ post_upgrade_info.stdout[0] | regex_search('version: .+') }}" msg: "{{ router_name }}: verified RouterOS {{ installed_version }} -> {{ latest_version }}."
when: installed_version != latest_version
tags: [upgrade, never]