Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 22 additions & 12 deletions grafana_backup/api_checks.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
from grafana_backup.commons import print_horizontal_line
from grafana_backup.dashboardApi import health_check, auth_check, uid_feature_check, paging_feature_check, contact_point_check
from grafana_backup.dashboardApi import (
auth_check,
contact_point_check,
health_check,
paging_feature_check,
uid_feature_check,
)


def main(settings):
Expand All @@ -12,37 +18,41 @@ def main(settings):
api_auth_check = settings.get('API_AUTH_CHECK')

if api_health_check:
(status, json_resp) = health_check(grafana_url,
http_get_headers, verify_ssl, client_cert, debug)
(status, json_resp) = health_check(grafana_url, http_get_headers, verify_ssl, client_cert, debug)
if not status == 200:
return (status, json_resp, None, None, None)

if api_auth_check:
(status, json_resp) = auth_check(grafana_url,
http_get_headers, verify_ssl, client_cert, debug)
(status, json_resp) = auth_check(grafana_url, http_get_headers, verify_ssl, client_cert, debug)
if not status == 200:
return (status, json_resp, None, None, None)

dashboard_uid_support, datasource_uid_support = uid_feature_check(
grafana_url, http_get_headers, verify_ssl, client_cert, debug)
grafana_url, http_get_headers, verify_ssl, client_cert, debug
)
if isinstance(dashboard_uid_support, str):
raise Exception(dashboard_uid_support)
if isinstance(datasource_uid_support, str):
raise Exception(datasource_uid_support)

paging_support = paging_feature_check(
grafana_url, http_get_headers, verify_ssl, client_cert, debug)
paging_support = paging_feature_check(grafana_url, http_get_headers, verify_ssl, client_cert, debug)
if isinstance(paging_support, str):
raise Exception(paging_support)

is_contact_point_available = contact_point_check(
grafana_url, http_get_headers, verify_ssl, client_cert, debug)
is_contact_point_available = contact_point_check(grafana_url, http_get_headers, verify_ssl, client_cert, debug)

print_horizontal_line()
if status == 200:
print("[Pre-Check] Server status is 'OK' !!")
else:
print("[Pre-Check] Server status is NOT OK !!: {0}".format(json_resp))
print('[Pre-Check] Server status is NOT OK !!: {0}'.format(json_resp))
print_horizontal_line()

return (status, json_resp, dashboard_uid_support, datasource_uid_support, paging_support, is_contact_point_available)
return (
status,
json_resp,
dashboard_uid_support,
datasource_uid_support,
paging_support,
is_contact_point_available,
)
25 changes: 20 additions & 5 deletions grafana_backup/archive.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from glob import glob
import os
import tarfile
import shutil
import tarfile
from glob import glob


def main(args, settings):
Expand All @@ -11,8 +11,23 @@ def main(args, settings):
archive_file = '{0}/{1}.tar.gz'.format(backup_dir, timestamp)
backup_files = list()

for folder_name in ['folders', 'datasources', 'dashboards', 'alert_channels', 'organizations', 'users', 'snapshots',
'dashboard_versions', 'annotations', 'library-elements', 'teams', 'team_members', 'alert_rules', 'contact_points', 'notification_policies']:
for folder_name in [
'folders',
'datasources',
'dashboards',
'alert_channels',
'organizations',
'users',
'snapshots',
'dashboard_versions',
'annotations',
'library-elements',
'teams',
'team_members',
'alert_rules',
'contact_points',
'notification_policies',
]:
backup_path = '{0}/{1}/{2}'.format(backup_dir, folder_name, timestamp)

for file_path in glob(backup_path):
Expand All @@ -22,7 +37,7 @@ def main(args, settings):
if os.path.exists(archive_file):
os.remove(archive_file)

with tarfile.open(archive_file, "w:gz") as tar:
with tarfile.open(archive_file, 'w:gz') as tar:
for file_path in backup_files:
tar.add(file_path)
shutil.rmtree(os.path.abspath(os.path.join(file_path, os.pardir)))
Expand Down
9 changes: 6 additions & 3 deletions grafana_backup/azure_storage_download.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from azure.storage.blob import BlobServiceClient
import io

from azure.storage.blob import BlobServiceClient


def main(args, settings):
arg_archive_file = args.get('<archive_file>', None)
Expand All @@ -10,10 +11,12 @@ def main(args, settings):

try:
blob_service_client = BlobServiceClient.from_connection_string(azure_storage_connection_string)
container_client = blob_service_client.get_blob_client(container=azure_storage_container_name, blob=arg_archive_file)
container_client = blob_service_client.get_blob_client(
container=azure_storage_container_name, blob=arg_archive_file
)
azure_storage_bytes = container_client.download_blob().readall()
azure_storage_data = io.BytesIO(azure_storage_bytes)
print("Download from Azure Storage was successful")
print('Download from Azure Storage was successful')
except Exception as e:
print(str(e))
return False
Expand Down
8 changes: 5 additions & 3 deletions grafana_backup/azure_storage_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ def main(args, settings):

try:
blob_service_client = BlobServiceClient.from_connection_string(azure_storage_connection_string)
container_client = blob_service_client.get_blob_client(container=azure_storage_container_name, blob=azure_file_name)
container_client = blob_service_client.get_blob_client(
container=azure_storage_container_name, blob=azure_file_name
)
with open(archive_file, 'rb') as data:
container_client.upload_blob(data)
print("Upload to Azure Storage was successful")
print('Upload to Azure Storage was successful')
except FileNotFoundError: # noqa: F821
print("The file was not found")
print('The file was not found')
return False
except Exception as e:
print(str(e))
Expand Down
25 changes: 13 additions & 12 deletions grafana_backup/cli.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from grafana_backup.constants import (PKG_NAME, PKG_VERSION, JSON_CONFIG_PATH)
from grafana_backup.save import main as save
from grafana_backup.restore import main as restore
from grafana_backup.delete import main as delete
from grafana_backup.tools import main as tools
from grafana_backup.grafanaSettings import main as conf
from docopt import docopt
import os
import sys

from docopt import docopt

from grafana_backup.constants import JSON_CONFIG_PATH, PKG_NAME, PKG_VERSION
from grafana_backup.delete import main as delete
from grafana_backup.grafanaSettings import main as conf
from grafana_backup.restore import main as restore
from grafana_backup.save import main as save
from grafana_backup.tools import main as tools

docstring = """
{0} {1}

Expand All @@ -24,22 +26,21 @@
-h --help Show this help message and exit
--version Get version information and exit
--config=<filename> Override default configuration path
--components=<> Comma separated list of individual components to backup (all by default); dashboard-versions can only be saved not restored.
--components=<> Comma separated list of individual components to backup (all by default);
dashboard-versions can only be saved not restored.
<folders,folder_permissions,dashboards,datasources,alert-channels,alert-rules,organizations,users,snapshots,dashboard-versions,annotations,library_elements,teams,team_members>

--no-archive Skip archive creation and do not delete unarchived files
(used for troubleshooting purposes)
""".format(PKG_NAME, PKG_VERSION)


args = docopt(docstring, help=False,
version='{0} {1}'.format(PKG_NAME, PKG_VERSION))
args = docopt(docstring, help=False, version='{0} {1}'.format(PKG_NAME, PKG_VERSION))


def main():
arg_config = args.get('--config', False)
default_config = '{0}/conf/grafanaSettings.json'.format(
os.path.dirname(__file__))
default_config = '{0}/conf/grafanaSettings.json'.format(os.path.dirname(__file__))

if arg_config:
settings = conf(arg_config)
Expand Down
16 changes: 9 additions & 7 deletions grafana_backup/commons.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import re, sys, json
import json
import re
import sys


def print_horizontal_line():
print('')
print("########################################")
print('########################################')
print('')


def log_response(resp):
status_code = resp.status_code
print("[DEBUG] resp status: {0}".format(status_code))
print('[DEBUG] resp status: {0}'.format(status_code))
try:
print("[DEBUG] resp body: {0}".format(resp.json()))
print('[DEBUG] resp body: {0}'.format(resp.json()))
except ValueError:
print("[DEBUG] resp body: {0}".format(to_python2_and_3_compatible_string(resp.text)))
print('[DEBUG] resp body: {0}'.format(to_python2_and_3_compatible_string(resp.text)))
return resp


Expand All @@ -39,12 +41,12 @@ def load_config(path=None):


def save_json(file_name, data, folder_path, extension, pretty_print):
pattern = "^db/|^uid/"
pattern = '^db/|^uid/'
if re.match(pattern, file_name):
file_name = re.sub(pattern, '', file_name)

file_path = folder_path + '/' + file_name + '.' + extension
with open(u"{0}".format(file_path), 'w') as f:
with open('{0}'.format(file_path), 'w') as f:
if pretty_print:
f.write(json.dumps(data, sort_keys=True, indent=4, separators=(',', ': ')))
else:
Expand Down
13 changes: 6 additions & 7 deletions grafana_backup/constants.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import os


if os.name == "nt":
homedir = os.environ["HOMEPATH"]
if os.name == 'nt':
homedir = os.environ['HOMEPATH']
else:
homedir = os.environ["HOME"]
homedir = os.environ['HOME']

PKG_NAME = "grafana-backup"
PKG_VERSION = "1.4.3"
JSON_CONFIG_PATH = "{0}/.grafana-backup.json".format(homedir)
PKG_NAME = 'grafana-backup'
PKG_VERSION = '1.4.3'
JSON_CONFIG_PATH = '{0}/.grafana-backup.json'.format(homedir)
7 changes: 5 additions & 2 deletions grafana_backup/create_alert_channel.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json

from grafana_backup.dashboardApi import create_alert_channel


Expand All @@ -13,5 +14,7 @@ def main(args, settings, file_path):
data = f.read()

alert_channel = json.loads(data)
result = create_alert_channel(json.dumps(alert_channel), grafana_url, http_post_headers, verify_ssl, client_cert, debug)
print("create alert_channel: {0}, status: {1}, msg: {2}".format(alert_channel['name'], result[0], result[1]))
result = create_alert_channel(
json.dumps(alert_channel), grafana_url, http_post_headers, verify_ssl, client_cert, debug
)
print('create alert_channel: {0}, status: {1}, msg: {2}'.format(alert_channel['name'], result[0], result[1]))
38 changes: 27 additions & 11 deletions grafana_backup/create_alert_rule.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import json
from grafana_backup.dashboardApi import get_alert_rule, create_alert_rule, update_alert_rule, get_grafana_version

from packaging import version

from grafana_backup.dashboardApi import create_alert_rule, get_alert_rule, get_grafana_version, update_alert_rule


def main(args, settings, file_path):
grafana_url = settings.get('GRAFANA_URL')
Expand All @@ -12,7 +14,7 @@ def main(args, settings, file_path):
debug = settings.get('DEBUG')
grafana_version_string = settings.get('GRAFANA_VERSION')
if grafana_version_string:
grafana_version = version.parse(grafana_version_string)
grafana_version = version.parse(grafana_version_string)

with open(file_path, 'r') as f:
data = f.read()
Expand All @@ -21,22 +23,36 @@ def main(args, settings, file_path):
grafana_version = get_grafana_version(grafana_url, verify_ssl, http_get_headers)
except KeyError as error:
if not grafana_version:
raise Exception("Grafana version is not set.") from error
raise Exception('Grafana version is not set.') from error

minimum_version = version.parse('9.4.0')

if minimum_version <= grafana_version:
alert_rule = json.loads(data)
del alert_rule['id']
uid = alert_rule['uid']
get_response= get_alert_rule(uid, grafana_url, http_get_headers, verify_ssl, client_cert, debug)
status_code=get_response[0]
print("Got a code: {0}", status_code)
get_response = get_alert_rule(uid, grafana_url, http_get_headers, verify_ssl, client_cert, debug)
status_code = get_response[0]
print('Got a code: {0}', status_code)
if status_code == 404:
http_post_headers['x-disable-provenance']='*'
result = create_alert_rule(json.dumps(alert_rule), grafana_url, http_post_headers, verify_ssl, client_cert, debug)
http_post_headers['x-disable-provenance'] = '*'
result = create_alert_rule(
json.dumps(alert_rule), grafana_url, http_post_headers, verify_ssl, client_cert, debug
)
else:
result = update_alert_rule(alert_rule['uid'], json.dumps(alert_rule), grafana_url, http_post_headers, verify_ssl, client_cert, debug)
print("create alert rule: {0}, status: {1}, msg: {2}".format(alert_rule['title'], result[0], result[1]))
result = update_alert_rule(
alert_rule['uid'],
json.dumps(alert_rule),
grafana_url,
http_post_headers,
verify_ssl,
client_cert,
debug,
)
print('create alert rule: {0}, status: {1}, msg: {2}'.format(alert_rule['title'], result[0], result[1]))
else:
print("Unable to create alert rules, requires Grafana version {0} or above. Current version is {1}".format(minimum_version, grafana_version))
print(
'Unable to create alert rules, requires Grafana version {0} or above. Current version is {1}'.format(
minimum_version, grafana_version
)
)
3 changes: 2 additions & 1 deletion grafana_backup/create_annotation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json

from grafana_backup.dashboardApi import create_annotation


Expand All @@ -14,4 +15,4 @@ def main(args, settings, file_path):

annotation = json.loads(data)
result = create_annotation(json.dumps(annotation), grafana_url, http_post_headers, verify_ssl, client_cert, debug)
print("create annotation: {0}, status: {1}, msg: {2}".format(annotation['id'], result[0], result[1]))
print('create annotation: {0}, status: {1}, msg: {2}'.format(annotation['id'], result[0], result[1]))
Loading