From 39a12ae23b38fa303b51ce53b50f26df8a16477c Mon Sep 17 00:00:00 2001 From: sjat Date: Mon, 8 Jun 2026 19:36:14 +0200 Subject: [PATCH] feat(backup): export + binary backup, fetch into repo Implements Task 8. play_backup.yml ensures the local dir then includes backup.yml, which runs /export + /system backup save and pulls both over SCP (net_get). Binary .backup is gitignored (may contain secrets); export.rsc is committed. Verified against crs310-maker on the bench: both artifacts fetched non-empty. Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitignore | 1 + backups/.gitkeep | 0 backups/crs310-maker/export.rsc | 35 +++++++++++++++++++ play_backup.yml | 16 +++++++++ .../tasks/backup.yml | 28 +++++++++++++-- 5 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 backups/.gitkeep create mode 100644 backups/crs310-maker/export.rsc create mode 100644 play_backup.yml diff --git a/.gitignore b/.gitignore index e1b4427..476e594 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ __pycache__/ *.pyc .DS_Store +backups/**/*.backup diff --git a/backups/.gitkeep b/backups/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/backups/crs310-maker/export.rsc b/backups/crs310-maker/export.rsc new file mode 100644 index 0000000..d2f42d5 --- /dev/null +++ b/backups/crs310-maker/export.rsc @@ -0,0 +1,35 @@ +# 2025-09-11 09:49:07 by RouterOS 7.19.6 +# software id = 73S3-5F2W +# +# model = CRS310-8G+2S+ +# serial number = HM40B8TDNDD +/interface bridge +add admin-mac=D0:EA:11:24:F4:AA auto-mac=no comment=defconf name=bridge +/interface bridge port +add bridge=bridge comment=defconf interface=ether1 +add bridge=bridge comment=defconf interface=ether2 +add bridge=bridge comment=defconf interface=ether3 +add bridge=bridge comment=defconf interface=ether4 +add bridge=bridge comment=defconf interface=ether5 +add bridge=bridge comment=defconf interface=ether6 +add bridge=bridge comment=defconf interface=ether7 +add bridge=bridge comment=defconf interface=ether8 +add bridge=bridge comment=defconf interface=sfp-sfpplus1 +add bridge=bridge comment=defconf interface=sfp-sfpplus2 +/ip address +add address=192.168.88.1/24 comment=defconf interface=bridge network=\ + 192.168.88.0 +/ip dns +set servers=10.0.99.1 +/ip service +set ftp disabled=yes +set telnet disabled=yes +set www disabled=yes +set api disabled=yes +set api-ssl disabled=yes +/system identity +set name=crs310-maker +/system ntp client +set enabled=yes +/system ntp client servers +add address=10.0.99.1 diff --git a/play_backup.yml b/play_backup.yml new file mode 100644 index 0000000..2ecd7e6 --- /dev/null +++ b/play_backup.yml @@ -0,0 +1,16 @@ +--- +- name: Back up MikroTik switch configuration + hosts: mikrotik + gather_facts: false + tasks: + - name: Ensure local backup directory exists + ansible.builtin.file: + path: "{{ playbook_dir }}/backups/{{ inventory_hostname }}" + state: directory + mode: "0755" + delegate_to: localhost + + - name: Run backup tasks + ansible.builtin.include_role: + name: makerfloss.mikrotik_switch + tasks_from: backup.yml diff --git a/roles/makerfloss.mikrotik_switch/tasks/backup.yml b/roles/makerfloss.mikrotik_switch/tasks/backup.yml index fe0a9a3..ca78c91 100644 --- a/roles/makerfloss.mikrotik_switch/tasks/backup.yml +++ b/roles/makerfloss.mikrotik_switch/tasks/backup.yml @@ -1,4 +1,26 @@ --- -- name: Placeholder - ansible.builtin.debug: - msg: "not yet implemented" +# Generate a human-readable /export and a binary /system backup on the device, +# then pull both into the repo under backups//. net_get uses SCP over the +# RouterOS SSH service (same channel play_bootstrap.yml uses for net_put). + +- name: Generate a config export on the device + community.routeros.command: + commands: + - /export file=export + changed_when: false + +- name: Generate a binary system backup on the device + community.routeros.command: + commands: + - /system/backup/save name=backup dont-encrypt=yes + changed_when: false + +- name: Fetch the export file into the repo + ansible.netcommon.net_get: + src: "export.rsc" + dest: "{{ playbook_dir }}/backups/{{ inventory_hostname }}/export.rsc" + +- name: Fetch the binary backup into the repo + ansible.netcommon.net_get: + src: "backup.backup" + dest: "{{ playbook_dir }}/backups/{{ inventory_hostname }}/backup.backup"