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