First commit
This commit is contained in:
parent
be761332d8
commit
dfd25c3a47
37
README.md
37
README.md
@ -1,3 +1,36 @@
|
||||
# MikrotikBackup_git
|
||||
# Mikrotik RouterOS backup script
|
||||
|
||||
Python skripta, ki naredi backup mikrotikovih naprav in naloži backupe na git strežnik, če se je konfiguracija spremenila.
|
||||
## Postopek
|
||||
### Strežnik
|
||||
Najprej je potrebna priprava strežnika. Skripta bi morala delovati na vseh sistemih na katerih teče python.
|
||||
Na strežniku mora biti nameščen Python3 ter nekaj knjižnic: paramiko, git, time. Na strežniku mora biti ustvarjen SSH ključ.
|
||||
|
||||
### Mikrotikove naprave
|
||||
Na Mikrotikovih napravah, za katere želimo narediti varnostno kopijo konfiguracije na Git strežniku, je potrebno ustvariti "skupino" (oz. group) za uporabnika s sledečimi pravicami: ssh, ftp, read, write, sensitive.
|
||||
Nato je treba ustvariti uporabnika, ki ima dodan prej generiran javni SSH ključ. Tako bo omogočena varna prijava preko protokola SSH na Mikrotikovo napravo brez gesla.
|
||||
Zagotovljeno mora biti tudi, da ima strežnik dostop do vrat 22 oz. nastavljenih SSH vrat na Mikrotiku.
|
||||
|
||||
### Git Strežnik
|
||||
Uporabniški račun, preko katerega bodo kopije konfiguracij nalagane na strežnik, mora imeti dodan javni SSH ključ strežnika, ki omogoča varno prijavo brez gesla.
|
||||
Pripravljen mora biti repozitorij, ki mora biti tudi kloniran na strežnik namenjen varnostnim kopijam. Nujno je, da so znotraj repozitorija pripravljene mape, ki imajo enako ime kot lokacije na seznamu.
|
||||
|
||||
### Priprava skripte
|
||||
|
||||
Za delovanje skripte so potrebne 3 datoteke:
|
||||
- main.py -> Glavna skripta
|
||||
- config.py -> Parametri potrebni za delovanje skripte
|
||||
- devices.csv -> Seznam naprav, ki jih bo strežnik varnostno kopiral
|
||||
|
||||
Ko so naprave vpisane v seznam in so potrebni parametri pripravljeni v datoteki config.py, je potrebno le še pognati skripto oziroma nastaviti avtomatsko izvajanje skripte, na primer enkrat na dan.
|
||||
Skripta je zasnovana tako, da na Git strežnik nalaga le popravke. Če sprememb ni, skripta ne naloži ničesar.
|
||||
|
||||
Primer datoteke devices.csv
|
||||
|
||||
```
|
||||
Location,DeviceName,HostName,Port,User
|
||||
Nanos,Router,192.168.2.3,22,backupscript
|
||||
```
|
||||
|
||||
V tem primeru se torej skripta priklaplja na router na **Nanosu**, ki ima IP **192.168.2.3**, SSH posluša na vratih **22**. Za priklop nanj je uporabljen uporabnik **backupscript**. Kot prej rečeno je nujno, da je tudi ustvarjena mapa **Nanos** oz. mapa z imenom uporabljene lokacije.
|
||||
|
||||
Skripta izvede varnostno kopijo na vseh napravah, ki so vpisane na seznam.
|
3
config.py
Normal file
3
config.py
Normal file
@ -0,0 +1,3 @@
|
||||
devicescsv_path = "/path/to/devices.csv"
|
||||
repository_path= "/path/to/cloned/repository"
|
||||
key_path = "/path/to/private/ssh/key/.ssh/id_rsa"
|
1
devices.csv
Normal file
1
devices.csv
Normal file
@ -0,0 +1 @@
|
||||
Location,DeviceName,HostName,Port,User
|
|
76
main.py
Normal file
76
main.py
Normal file
@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import paramiko
|
||||
from git import Repo
|
||||
import csv
|
||||
import time
|
||||
from config import * #config variables from config.py
|
||||
|
||||
#Check entries in the devices.csv document and import them into the dictionary
|
||||
devices = [] #dictionary
|
||||
with open(devicescsv_path,'r') as devicelist:
|
||||
list = csv.DictReader(devicelist)
|
||||
for row in list:
|
||||
devices.append(row)
|
||||
|
||||
#for each entry do an export and download it
|
||||
for device in devices:
|
||||
file_path = repository_path + "/" + device["Location"] + "/" + device["Location"] + "_" + device["DeviceName"] + ".rsc"
|
||||
# Create an SSH client instance
|
||||
ssh_client = paramiko.SSHClient()
|
||||
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
|
||||
try:
|
||||
# Connect to the server
|
||||
ssh_client.connect(hostname = device["HostName"], port = device["Port"], username = device["User"], pkey = paramiko.RSAKey.from_private_key_file(key_path))
|
||||
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
|
||||
else:
|
||||
print("Connected to " + device["HostName"])
|
||||
#Export config
|
||||
ssh_client.exec_command("export file=" + device["Location"] + "_" + device["DeviceName"] + ".rsc show-sensitive")
|
||||
print("Export commanded")
|
||||
time.sleep(10) #Wait for ten seconds to make sure latest export is prepared before download
|
||||
|
||||
#Download Config
|
||||
ssh_client.open_sftp().get(device["Location"] + "_" + device["DeviceName"] + ".rsc", file_path)
|
||||
print("File downloaded successfully!")
|
||||
|
||||
finally:
|
||||
# Close the SSH connection
|
||||
ssh_client.close()
|
||||
print("Connection closed")
|
||||
|
||||
# Open exported document, remove date and time of export
|
||||
with open(file_path, 'r') as file:
|
||||
lines = file.readlines()
|
||||
|
||||
if lines: # Check if the file is not empty
|
||||
lines[0] = lines[0][:2] + lines[0][25:] #remove date and time of export
|
||||
|
||||
with open(file_path, 'w') as file:
|
||||
file.writelines(lines)
|
||||
|
||||
repository = Repo(repository_path)
|
||||
|
||||
if repository.bare:
|
||||
print("The repository is bare")
|
||||
exit()
|
||||
|
||||
if repository.is_dirty(untracked_files=True): #Check if there are any differences
|
||||
print("Changes detected in the repository.")
|
||||
|
||||
repository.git.add(all=True) #Stage all changes
|
||||
print("Staged all changes.")
|
||||
|
||||
commit_message = time.strftime("%Y.%m.%d %H:%M:%S", time.localtime()) #commit changes
|
||||
repository.index.commit(commit_message)
|
||||
print("Committed changes with message:" + commit_message)
|
||||
|
||||
origin = repository.remote(name='origin') #push
|
||||
origin.push()
|
||||
print("Pushed changes to the remote repository.")
|
||||
else:
|
||||
print("No changes to commit.")
|
Loading…
x
Reference in New Issue
Block a user