-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathmtbackup.py
More file actions
executable file
·119 lines (100 loc) · 3.68 KB
/
mtbackup.py
File metadata and controls
executable file
·119 lines (100 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/python
# vim:encoding=utf8
"""RouterOS (Mikrotik) Backup over SSH"""
__author__ = "Jiří Zapletal"
__license__ = "MIT"
import sys
from os import path
from time import sleep
import socket
try:
import paramiko
except ImportError:
print "ERROR: missing paramiko module (pip install paramiko)"
sys.exit(1)
# parse args
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-c", dest="config", help="configuration file",
metavar="FILE", default="mtbackup.conf")
parser.add_option("-o", dest="output", help="output directory",
default="backups")
parser.add_option("-n", dest="keep", help="keep n recent backups", default=5,
type="int")
parser.add_option("-a", dest="autokey", help="accept all ssh server keys",
action="store_true", default=False)
parser.add_option("-s", dest="skip_backup_cmd",
help="skip backup command (run it via ros scheduler)",
action="store_true", default=False)
parser.add_option("-d", dest="debug", help="log debug info into ssh.log",
action="store_true", default=False)
def download_backups(hostname, port, username, password, key_fn, options):
client = paramiko.SSHClient()
client.load_system_host_keys()
if options.autokey:
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print "[%s] connecting" % (hostname, )
try:
client.connect(hostname, port=port, username=username,
password=password, key_filename=key_fn,
allow_agent=False, look_for_keys=False)
except paramiko.SSHException as e:
print "[%s] ERROR: %s" % (hostname, e)
return
except socket.gaierror as e:
print "[%s] ERROR: %s" % (hostname, e)
return
print "[%s] connected" % (hostname, )
# run backup command
if not options.skip_backup_cmd:
print "[%s] running backup command" % (hostname, )
stdin, stdout, stderr = client.exec_command('/system backup save')
stdout.read(), stderr.read()
# wait for completion
sleep(5)
# downloads all backups
sftp = client.open_sftp()
for fn in sftp.listdir():
outfn = path.join(options.output, fn)
if fn.endswith('.backup') and not path.exists(outfn):
print "[%s] downloading backup: %s" % (hostname, fn)
sftp.get(fn, outfn)
sftp.close()
# remove old backups, keep last 5
sftp = client.open_sftp()
lst = sftp.listdir_attr()
# filter only *.backup
lst = filter(lambda x: x.filename.endswith('.backup'), lst)
# sort by create time
lst = sorted(lst, key=lambda x: x.st_mtime, reverse=True)[options.keep:]
for fn in lst:
print "[%s] removing old backups: %s" % (hostname, fn.filename)
sftp.remove(fn.filename)
sftp.close()
client.close()
if __name__ == "__main__":
(options, args) = parser.parse_args()
# enable debugging
if options.debug:
print "logging debugging output into ssh.log"
paramiko.util.log_to_file('ssh.log')
# sanity check
if options.keep < 0:
options.keep = 5
# read config file
for line in open(options.config):
# skip comments
if line.startswith("#"):
continue
line = line.strip().split()
# skip blank lines
if len(line) == 0:
continue
# unwrap and download
(hostname, port, user, password, key_fn) = line
if password == '-':
password = None
if key_fn == '-':
key_fn = None
download_backups(hostname, int(port), user, password, key_fn, options)
sys.exit(0)