-
Notifications
You must be signed in to change notification settings - Fork 277
/
Copy pathrestore.py
executable file
·147 lines (127 loc) · 6.43 KB
/
restore.py
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
from grafana_backup.commons import print_horizontal_line
from grafana_backup.create_org import main as create_org
from grafana_backup.api_checks import main as api_checks
from grafana_backup.create_folder import main as create_folder
from grafana_backup.update_folder_permissions import main as update_folder_permissions
from grafana_backup.create_datasource import main as create_datasource
from grafana_backup.create_dashboard import main as create_dashboard
from grafana_backup.create_alert_channel import main as create_alert_channel
from grafana_backup.create_user import main as create_user
from grafana_backup.s3_download import main as s3_download
from grafana_backup.azure_storage_download import main as azure_storage_download
from grafana_backup.gcs_download import main as gcs_download
from glob import glob
import sys, tarfile, tempfile, os, shutil, fnmatch, collections
def main(args, settings):
def open_compressed_backup(compressed_backup):
try:
tar = tarfile.open(fileobj=compressed_backup, mode='r:gz')
return tar
except Exception as e:
print(str(e))
sys.exit(1)
arg_archive_file = args.get('<archive_file>', None)
aws_s3_bucket_name = settings.get('AWS_S3_BUCKET_NAME')
azure_storage_container_name = settings.get('AZURE_STORAGE_CONTAINER_NAME')
gcs_bucket_name = settings.get('GCS_BUCKET_NAME')
(status, json_resp, uid_support, paging_support) = api_checks(settings)
# Do not continue if API is unavailable or token is not valid
if not status == 200:
sys.exit(1)
# Use tar data stream if S3 bucket name is specified
if aws_s3_bucket_name:
print('Download archives from S3:')
s3_data = s3_download(args, settings)
tar = open_compressed_backup(s3_data)
elif azure_storage_container_name:
print('Download archives from Azure:')
azure_storage_data = azure_storage_download(args, settings)
tar = open_compressed_backup(azure_storage_data)
elif gcs_bucket_name:
print('Download archives from GCS:')
gcs_storage_data = gcs_download(args, settings)
tar = open_compressed_backup(gcs_storage_data)
else:
try:
tarfile.is_tarfile(name=arg_archive_file)
except IOError as e:
print(str(e))
sys.exit(1)
try:
tar = tarfile.open(name=arg_archive_file, mode='r:gz')
except Exception as e:
print(str(e))
sys.exit(1)
restore_functions = collections.OrderedDict()
restore_functions['folder'] = create_folder
restore_functions['datasource'] = create_datasource
restore_functions['dashboard'] = create_dashboard
restore_functions['alert_channel'] = create_alert_channel
restore_functions['organization'] = create_org
restore_functions['user'] = create_user
if sys.version_info >= (3,):
with tempfile.TemporaryDirectory() as tmpdir:
tar.extractall(tmpdir)
tar.close()
restore_components(args, settings, restore_functions, tmpdir)
else:
tmpdir = tempfile.mkdtemp()
tar.extractall(tmpdir)
tar.close()
restore_components(args, settings, restore_functions, tmpdir)
try:
shutil.rmtree(tmpdir)
except OSError as e:
print("Error: %s : %s" % (tmpdir, e.strerror))
def restore_components(args, settings, restore_functions, tmpdir):
arg_components = args.get('--components', False)
if arg_components:
arg_components_list = arg_components.split(',')
# Restore only the components that provided via an argument
# but must also exist in extracted archive
for ext in arg_components_list:
if sys.version_info >= (3,):
for file_path in glob('{0}/**/*.{1}'.format(tmpdir, ext[:-1]), recursive=True):
print('restoring {0}: {1}'.format(ext, file_path))
restore_functions[ext[:-1]](args, settings, file_path)
else:
for root, dirnames, filenames in os.walk('{0}'.format(tmpdir)):
for filename in fnmatch.filter(filenames, '*.{0}'.format(ext[:-1])):
file_path = os.path.join(root, filename)
print('restoring {0}: {1}'.format(ext, file_path))
restore_functions[ext[:-1]](args, settings, file_path)
else:
# Restore every component included in extracted archive
for ext in restore_functions.keys():
if sys.version_info >= (3,):
for file_path in glob('{0}/**/*.{1}'.format(tmpdir, ext), recursive=True):
print('restoring {0}: {1}'.format(ext, file_path))
restore_functions[ext](args, settings, file_path)
else:
for root, dirnames, filenames in os.walk('{0}'.format(tmpdir)):
for filename in fnmatch.filter(filenames, '*.{0}'.format(ext)):
file_path = os.path.join(root, filename)
print('restoring {0}: {1}'.format(ext, file_path))
restore_functions[ext](args, settings, file_path)
def restore_from_dir(args, arg_components, settings, restore_dir):
restore_functions = { 'folder': create_folder,
'folder_permissions': update_folder_permissions,
'datasource': create_datasource,
'dashboard': create_dashboard,
'alert_channel': create_alert_channel,
'organization': create_org,
'user': create_user}
if arg_components:
arg_components_list = arg_components.split(',')
# Restore only the components that provided via an argument
# but must also exist in extracted archive
for ext in arg_components_list:
for file_path in glob('{0}/**/*.{1}'.format(restore_dir, ext[:-1]), recursive=True):
print('restoring {0}: {1}'.format(ext, file_path))
restore_functions[ext[:-1]](args, settings, file_path)
else:
# Restore every component included in extracted archive
for ext in restore_functions.keys():
for file_path in glob('{0}/**/*.{1}'.format(restore_dir, ext), recursive=True):
print('restoring {0}: {1}'.format(ext, file_path))
restore_functions[ext](args, settings, file_path)