diff --git a/grafana_backup/api_checks.py b/grafana_backup/api_checks.py index 490c889..17ef511 100644 --- a/grafana_backup/api_checks.py +++ b/grafana_backup/api_checks.py @@ -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): @@ -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, + ) diff --git a/grafana_backup/archive.py b/grafana_backup/archive.py index 1744e76..603a63f 100755 --- a/grafana_backup/archive.py +++ b/grafana_backup/archive.py @@ -1,7 +1,7 @@ -from glob import glob import os -import tarfile import shutil +import tarfile +from glob import glob def main(args, settings): @@ -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): @@ -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))) diff --git a/grafana_backup/azure_storage_download.py b/grafana_backup/azure_storage_download.py index cc4ecde..845e349 100644 --- a/grafana_backup/azure_storage_download.py +++ b/grafana_backup/azure_storage_download.py @@ -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('', None) @@ -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 diff --git a/grafana_backup/azure_storage_upload.py b/grafana_backup/azure_storage_upload.py index e8f77e4..e0c77ea 100644 --- a/grafana_backup/azure_storage_upload.py +++ b/grafana_backup/azure_storage_upload.py @@ -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)) diff --git a/grafana_backup/cli.py b/grafana_backup/cli.py index 051ed31..c98bc98 100755 --- a/grafana_backup/cli.py +++ b/grafana_backup/cli.py @@ -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} @@ -24,7 +26,8 @@ -h --help Show this help message and exit --version Get version information and exit --config= 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. --no-archive Skip archive creation and do not delete unarchived files @@ -32,14 +35,12 @@ """.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) diff --git a/grafana_backup/commons.py b/grafana_backup/commons.py index 8d4a6ce..f79e017 100755 --- a/grafana_backup/commons.py +++ b/grafana_backup/commons.py @@ -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 @@ -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: diff --git a/grafana_backup/constants.py b/grafana_backup/constants.py index 6b5bbe4..f2730a0 100644 --- a/grafana_backup/constants.py +++ b/grafana_backup/constants.py @@ -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) diff --git a/grafana_backup/create_alert_channel.py b/grafana_backup/create_alert_channel.py index d13a25a..dc33177 100644 --- a/grafana_backup/create_alert_channel.py +++ b/grafana_backup/create_alert_channel.py @@ -1,4 +1,5 @@ import json + from grafana_backup.dashboardApi import create_alert_channel @@ -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])) diff --git a/grafana_backup/create_alert_rule.py b/grafana_backup/create_alert_rule.py index 9a3fcde..92a0e7d 100644 --- a/grafana_backup/create_alert_rule.py +++ b/grafana_backup/create_alert_rule.py @@ -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') @@ -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() @@ -21,7 +23,7 @@ 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') @@ -29,14 +31,28 @@ def main(args, settings, file_path): 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 + ) + ) diff --git a/grafana_backup/create_annotation.py b/grafana_backup/create_annotation.py index 1a20fb1..68b48dd 100644 --- a/grafana_backup/create_annotation.py +++ b/grafana_backup/create_annotation.py @@ -1,4 +1,5 @@ import json + from grafana_backup.dashboardApi import create_annotation @@ -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])) diff --git a/grafana_backup/create_contact_point.py b/grafana_backup/create_contact_point.py index 138879d..38414ce 100644 --- a/grafana_backup/create_contact_point.py +++ b/grafana_backup/create_contact_point.py @@ -1,7 +1,14 @@ import json -from grafana_backup.dashboardApi import create_contact_point, get_grafana_version, search_contact_points, update_contact_point + from packaging import version +from grafana_backup.dashboardApi import ( + create_contact_point, + get_grafana_version, + search_contact_points, + update_contact_point, +) + def main(args, settings, file_path): grafana_url = settings.get('GRAFANA_URL') @@ -15,7 +22,7 @@ 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') @@ -30,23 +37,39 @@ def main(args, settings, file_path): # Successfully received list of contact points. # Append contact points to list of existing contact points for ecp in result[1]: - existing_contact_points.append(ecp["uid"]) + existing_contact_points.append(ecp['uid']) contact_points = json.loads(data) for cp in contact_points: - if cp["uid"] in existing_contact_points: - print("Contact point {0} already exists, updating".format(cp["uid"])) - result = update_contact_point(cp["uid"], json.dumps(cp), grafana_url, http_post_headers, verify_ssl, client_cert, debug) + if cp['uid'] in existing_contact_points: + print('Contact point {0} already exists, updating'.format(cp['uid'])) + result = update_contact_point( + cp['uid'], json.dumps(cp), grafana_url, http_post_headers, verify_ssl, client_cert, debug + ) if result[0] == 202: - print("Successfully updated contact point") + print('Successfully updated contact point') else: - print("[ERROR] Contact point {0} failed to update. Return code:{1} - {2}".format(cp["uid"], result[0], result[1])) + print( + '[ERROR] Contact point {0} failed to update. Return code:{1} - {2}'.format( + cp['uid'], result[0], result[1] + ) + ) else: - print("Contact point {0} does not exist, creating".format(cp["uid"])) - result = create_contact_point(json.dumps(cp), grafana_url, http_post_headers, verify_ssl, client_cert, debug) + print('Contact point {0} does not exist, creating'.format(cp['uid'])) + result = create_contact_point( + json.dumps(cp), grafana_url, http_post_headers, verify_ssl, client_cert, debug + ) if result[0] == 202: - print("Successfully create contact point") + print('Successfully create contact point') else: - print("[ERROR] Contact point {0} failed to create. Retufn code:{1} - {2}".format(cp["uid"], result[0], result[1])) + print( + '[ERROR] Contact point {0} failed to create. Retufn code:{1} - {2}'.format( + cp['uid'], result[0], result[1] + ) + ) else: - print("Unable to create contact points, requires Grafana version {0} or above. Current version is {1}".format(minimum_version, grafana_version)) + print( + 'Unable to create contact points, requires Grafana version {0} or above. Current version is {1}'.format( + minimum_version, grafana_version + ) + ) diff --git a/grafana_backup/create_dashboard.py b/grafana_backup/create_dashboard.py index fb2a20e..4b6479d 100755 --- a/grafana_backup/create_dashboard.py +++ b/grafana_backup/create_dashboard.py @@ -1,6 +1,7 @@ import json + from grafana_backup.commons import to_python2_and_3_compatible_string -from grafana_backup.dashboardApi import get_folder_id, create_dashboard +from grafana_backup.dashboardApi import create_dashboard, get_folder_id def main(args, settings, file_path): @@ -19,9 +20,9 @@ def main(args, settings, file_path): payload = { 'dashboard': content['dashboard'], 'folderId': get_folder_id(content, grafana_url, http_post_headers, verify_ssl, client_cert, debug), - 'overwrite': True + 'overwrite': True, } result = create_dashboard(json.dumps(payload), grafana_url, http_post_headers, verify_ssl, client_cert, debug) dashboard_title = to_python2_and_3_compatible_string(content['dashboard'].get('title', '')) - print("create dashboard {0} response status: {1}, msg: {2} \n".format(dashboard_title, result[0], result[1])) + print('create dashboard {0} response status: {1}, msg: {2} \n'.format(dashboard_title, result[0], result[1])) diff --git a/grafana_backup/create_datasource.py b/grafana_backup/create_datasource.py index 4a92e05..97d0bb2 100644 --- a/grafana_backup/create_datasource.py +++ b/grafana_backup/create_datasource.py @@ -1,4 +1,5 @@ import json + from grafana_backup.dashboardApi import create_datasource @@ -14,4 +15,4 @@ def main(args, settings, file_path): datasource = json.loads(data) result = create_datasource(json.dumps(datasource), grafana_url, http_post_headers, verify_ssl, client_cert, debug) - print("create datasource: {0}, status: {1}, msg: {2}".format(datasource['name'], result[0], result[1])) + print('create datasource: {0}, status: {1}, msg: {2}'.format(datasource['name'], result[0], result[1])) diff --git a/grafana_backup/create_folder.py b/grafana_backup/create_folder.py index d8629c9..1da5845 100644 --- a/grafana_backup/create_folder.py +++ b/grafana_backup/create_folder.py @@ -1,4 +1,5 @@ import json + from grafana_backup.dashboardApi import create_folder @@ -14,4 +15,4 @@ def main(args, settings, file_path): folder = json.loads(data) result = create_folder(json.dumps(folder), grafana_url, http_post_headers, verify_ssl, client_cert, debug) - print("create folder {0}, status: {1}, msg: {2}\n".format(folder.get('title', ''), result[0], result[1])) + print('create folder {0}, status: {1}, msg: {2}\n'.format(folder.get('title', ''), result[0], result[1])) diff --git a/grafana_backup/create_library_element.py b/grafana_backup/create_library_element.py index db82f50..9afb311 100644 --- a/grafana_backup/create_library_element.py +++ b/grafana_backup/create_library_element.py @@ -1,4 +1,5 @@ import json + from grafana_backup.dashboardApi import create_library_element, get_folder @@ -15,14 +16,12 @@ def main(args, settings, file_path): # Library Elements can only be created referencing a folder id. However, this folder id is not unique across Grafana # instances. Therefore, we need to first find the folder id by the given folder uid. library_element = json.loads(data) - folder_uid = library_element["meta"]["folderUid"] - folder_id_response = get_folder( - folder_uid, grafana_url, http_post_headers, verify_ssl, client_cert, debug - )[1] + folder_uid = library_element['meta']['folderUid'] + folder_id_response = get_folder(folder_uid, grafana_url, http_post_headers, verify_ssl, client_cert, debug)[1] if isinstance(folder_id_response, list): - library_element["folderUid"] = folder_id_response[0]['uid'] + library_element['folderUid'] = folder_id_response[0]['uid'] else: - library_element["folderUid"] = folder_id_response['uid'] + library_element['folderUid'] = folder_id_response['uid'] result = create_library_element( json.dumps(library_element), grafana_url, @@ -31,8 +30,4 @@ def main(args, settings, file_path): client_cert, debug, ) - print( - "create library_elements: {0}, status: {1}, msg: {2}".format( - library_element["name"], result[0], result[1] - ) - ) + print('create library_elements: {0}, status: {1}, msg: {2}'.format(library_element['name'], result[0], result[1])) diff --git a/grafana_backup/create_org.py b/grafana_backup/create_org.py index 7ab3ccf..467f714 100755 --- a/grafana_backup/create_org.py +++ b/grafana_backup/create_org.py @@ -1,4 +1,5 @@ import json + from grafana_backup.dashboardApi import create_org, update_org @@ -14,13 +15,25 @@ def main(args, settings, file_path): data = f.read() content = json.loads(data) - org_id = content["id"] + org_id = content['id'] - if (org_id == 1): - result = update_org(org_id, json.dumps(content), grafana_url, http_post_headers_basic_auth, verify_ssl, client_cert, debug) - print('update org "{0}" response status: {1}, msg: {2} \n'.format(content.get('name', ''), result[0], result[1])) + if org_id == 1: + result = update_org( + org_id, json.dumps(content), grafana_url, http_post_headers_basic_auth, verify_ssl, client_cert, debug + ) + print( + 'update org "{0}" response status: {1}, msg: {2} \n'.format( + content.get('name', ''), result[0], result[1] + ) + ) else: - result = create_org(json.dumps(content), grafana_url, http_post_headers_basic_auth, verify_ssl, client_cert, debug) - print('create org "{0}" response status: {1}, msg: {2} \n'.format(content.get('name', ''), result[0], result[1])) + result = create_org( + json.dumps(content), grafana_url, http_post_headers_basic_auth, verify_ssl, client_cert, debug + ) + print( + 'create org "{0}" response status: {1}, msg: {2} \n'.format( + content.get('name', ''), result[0], result[1] + ) + ) else: print('[ERROR] Restoring organizations needs to set GRAFANA_ADMIN_ACCOUNT and GRAFANA_ADMIN_PASSWORD first. \n') diff --git a/grafana_backup/create_snapshot.py b/grafana_backup/create_snapshot.py index c373e15..64e2c41 100644 --- a/grafana_backup/create_snapshot.py +++ b/grafana_backup/create_snapshot.py @@ -1,4 +1,5 @@ import json + from grafana_backup.dashboardApi import create_snapshot @@ -16,10 +17,12 @@ def main(args, settings, file_path): try: snapshot['name'] = snapshot['dashboard']['title'] except KeyError: - snapshot['name'] = "Untitled Snapshot" + snapshot['name'] = 'Untitled Snapshot' - (status, content) = create_snapshot(json.dumps(snapshot), grafana_url, http_post_headers, verify_ssl, client_cert, debug) + (status, content) = create_snapshot( + json.dumps(snapshot), grafana_url, http_post_headers, verify_ssl, client_cert, debug + ) if status == 200: - print("create snapshot: {0}, status: {1}, msg: {2}".format(snapshot['name'], status, content)) + print('create snapshot: {0}, status: {1}, msg: {2}'.format(snapshot['name'], status, content)) else: - print("creating snapshot {0} failed with status {1}".format(snapshot['name'], status)) + print('creating snapshot {0} failed with status {1}'.format(snapshot['name'], status)) diff --git a/grafana_backup/create_team.py b/grafana_backup/create_team.py index ccd9e1f..2b67926 100644 --- a/grafana_backup/create_team.py +++ b/grafana_backup/create_team.py @@ -1,4 +1,5 @@ import json + from grafana_backup.dashboardApi import create_team @@ -13,6 +14,5 @@ def main(args, settings, file_path): data = f.read() team = json.loads(data) - result = create_team(json.dumps(team), grafana_url, http_post_headers, verify_ssl, - client_cert, debug) - print("create teams: {0}, status: {1}, msg: {2}".format(team['name'], result[0], result[1])) + result = create_team(json.dumps(team), grafana_url, http_post_headers, verify_ssl, client_cert, debug) + print('create teams: {0}, status: {1}, msg: {2}'.format(team['name'], result[0], result[1])) diff --git a/grafana_backup/create_team_member.py b/grafana_backup/create_team_member.py index 5ccdc15..1533b94 100644 --- a/grafana_backup/create_team_member.py +++ b/grafana_backup/create_team_member.py @@ -19,18 +19,31 @@ def main(args, settings, file_path): team_member = json.loads(data) # A Team-Membership is a connection between a user and a team. However, userIds are not unique across Grafana # instances. Therefore, we need to first find the user id by the email. - user_id = get_user_by_email_or_username(urllib.parse.quote(team_member['email']), grafana_url, - http_get_headers_basic_auth, verify_ssl, client_cert, debug) + user_id = get_user_by_email_or_username( + urllib.parse.quote(team_member['email']), + grafana_url, + http_get_headers_basic_auth, + verify_ssl, + client_cert, + debug, + ) if 200 != user_id[0]: - user_id = get_user_by_email_or_username(urllib.parse.quote(team_member['name']), grafana_url, - http_get_headers_basic_auth, verify_ssl, client_cert, debug) + user_id = get_user_by_email_or_username( + urllib.parse.quote(team_member['name']), + grafana_url, + http_get_headers_basic_auth, + verify_ssl, + client_cert, + debug, + ) if 200 != user_id[0]: return - user = json.dumps({"userId": user_id[1]['id']}) - result = create_team_member(user, team_member['teamId'], grafana_url, http_post_headers, verify_ssl, - client_cert, debug) - print("create team member: {0}, status: {1}, msg: {2}".format(team_member['name'], result[0], result[1])) + user = json.dumps({'userId': user_id[1]['id']}) + result = create_team_member( + user, team_member['teamId'], grafana_url, http_post_headers, verify_ssl, client_cert, debug + ) + print('create team member: {0}, status: {1}, msg: {2}'.format(team_member['name'], result[0], result[1])) else: - print('[ERROR] Restoring team members needs to set GRAFANA_ADMIN_ACCOUNT and GRAFANA_ADMIN_PASSWORD first. \n') \ No newline at end of file + print('[ERROR] Restoring team members needs to set GRAFANA_ADMIN_ACCOUNT and GRAFANA_ADMIN_PASSWORD first. \n') diff --git a/grafana_backup/create_user.py b/grafana_backup/create_user.py index c4e593f..ba70fdd 100755 --- a/grafana_backup/create_user.py +++ b/grafana_backup/create_user.py @@ -1,5 +1,6 @@ import json -from grafana_backup.dashboardApi import create_user, add_user_to_org + +from grafana_backup.dashboardApi import add_user_to_org, create_user def main(args, settings, file_path): @@ -20,16 +21,27 @@ def main(args, settings, file_path): user = json.loads(data) user.update({'password': default_password}) - result = create_user(json.dumps(user), grafana_url, http_post_headers_basic_auth, verify_ssl, client_cert, debug) + result = create_user( + json.dumps(user), grafana_url, http_post_headers_basic_auth, verify_ssl, client_cert, debug + ) print('create user "{0}" response status: {1}, msg: {2} \n'.format(user.get('login', ''), result[0], result[1])) if result[0] == 200: for org in user.get('orgs', []): - org_payload = { - "loginOrEmail": user.get('login', 'email'), - "role": org.get('role', 'Viewer') - } - result = add_user_to_org(org.get('orgId'), json.dumps(org_payload), grafana_url, http_post_headers_basic_auth, verify_ssl, client_cert, debug) - print('add user "{0}" to org: {1} response status: {2}, msg: {3}'.format(user.get('login', ''), org.get('name', ''), result[0], result[1])) + org_payload = {'loginOrEmail': user.get('login', 'email'), 'role': org.get('role', 'Viewer')} + result = add_user_to_org( + org.get('orgId'), + json.dumps(org_payload), + grafana_url, + http_post_headers_basic_auth, + verify_ssl, + client_cert, + debug, + ) + print( + 'add user "{0}" to org: {1} response status: {2}, msg: {3}'.format( + user.get('login', ''), org.get('name', ''), result[0], result[1] + ) + ) else: print('[ERROR] Restoring users needs to set GRAFANA_ADMIN_ACCOUNT and GRAFANA_ADMIN_PASSWORD first. \n') diff --git a/grafana_backup/dashboardApi.py b/grafana_backup/dashboardApi.py index 3690c0f..3ea4220 100755 --- a/grafana_backup/dashboardApi.py +++ b/grafana_backup/dashboardApi.py @@ -1,28 +1,29 @@ -import re import json -import requests +import re import sys -from grafana_backup.commons import log_response, to_python2_and_3_compatible_string + +import requests from packaging import version +from grafana_backup.commons import log_response, to_python2_and_3_compatible_string + def health_check(grafana_url, http_get_headers, verify_ssl, client_cert, debug): url = '{0}/api/health'.format(grafana_url) - print("\n[Pre-Check] grafana health check: {0}".format(url)) + print('\n[Pre-Check] grafana health check: {0}'.format(url)) return send_grafana_get(url, http_get_headers, verify_ssl, client_cert, debug) def auth_check(grafana_url, http_get_headers, verify_ssl, client_cert, debug): url = '{0}/api/org'.format(grafana_url) - print("\n[Pre-Check] grafana auth check: {0}".format(url)) + print('\n[Pre-Check] grafana auth check: {0}'.format(url)) return send_grafana_get(url, http_get_headers, verify_ssl, client_cert, debug) def uid_feature_check(grafana_url, http_get_headers, verify_ssl, client_cert, debug): # Get first dashboard on first page print("\n[Pre-Check] grafana uid feature check: calling 'search_dashboard'") - (status, content) = search_dashboard(1, 1, grafana_url, - http_get_headers, verify_ssl, client_cert, debug) + (status, content) = search_dashboard(1, 1, grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200 and len(content): if 'uid' in content[0]: dashboard_uid_support = True @@ -30,15 +31,13 @@ def uid_feature_check(grafana_url, http_get_headers, verify_ssl, client_cert, de dashboard_uid_support = False else: if len(content): - dashboard_uid_support = "get dashboards failed, status: {0}, msg: {1}".format( - status, content) + dashboard_uid_support = 'get dashboards failed, status: {0}, msg: {1}'.format(status, content) else: # No dashboards exist, disable uid feature dashboard_uid_support = False # Get first datasource print("\n[Pre-Check] grafana uid feature check: calling 'search_datasource'") - (status, content) = search_datasource(grafana_url, - http_get_headers, verify_ssl, client_cert, debug) + (status, content) = search_datasource(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200 and len(content): if 'uid' in content[0]: datasource_uid_support = True @@ -46,8 +45,7 @@ def uid_feature_check(grafana_url, http_get_headers, verify_ssl, client_cert, de datasource_uid_support = False else: if len(content): - datasource_uid_support = "get datasources failed, status: {0}, msg: {1}".format( - status, content) + datasource_uid_support = 'get datasources failed, status: {0}, msg: {1}'.format(status, content) else: # No datasources exist, disable uid feature datasource_uid_support = False @@ -59,23 +57,18 @@ def paging_feature_check(grafana_url, http_get_headers, verify_ssl, client_cert, print("\n[Pre-Check] grafana paging_feature_check: calling 'search_dashboard'") def get_first_dashboard_by_page(page): - (status, content) = search_dashboard(page, 1, grafana_url, - http_get_headers, verify_ssl, client_cert, debug) + (status, content) = search_dashboard(page, 1, grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200 and len(content): if sys.version_info[0] > 2: - content[0] = {k: to_python2_and_3_compatible_string( - v) for k, v in content[0].items()} - dashboard_values = sorted( - content[0].items(), key=lambda kv: str(kv[1])) + content[0] = {k: to_python2_and_3_compatible_string(v) for k, v in content[0].items()} + dashboard_values = sorted(content[0].items(), key=lambda kv: str(kv[1])) else: - content[0] = {k: to_python2_and_3_compatible_string( - unicode(v)) for k, v in content[0].iteritems()} - dashboard_values = sorted( - content[0].iteritems(), key=lambda kv: str(kv[1])) + content[0] = {k: to_python2_and_3_compatible_string(str(v)) for k, v in content[0].iteritems()} + dashboard_values = sorted(content[0].iteritems(), key=lambda kv: str(kv[1])) return True, dashboard_values else: if len(content): - return False, "get dashboards failed, status: {0}, msg: {1}".format(status, content) + return False, 'get dashboards failed, status: {0}, msg: {1}'.format(status, content) else: # No dashboards exist, disable paging feature return False, False @@ -103,9 +96,8 @@ def get_first_dashboard_by_page(page): def contact_point_check(grafana_url, http_get_headers, verify_ssl, client_cert, debug): - print("\n[Pre-Check] grafana contact_point api check") - (status, content) = search_contact_points( - grafana_url, http_get_headers, verify_ssl, client_cert, debug) + print('\n[Pre-Check] grafana contact_point api check') + (status, content) = search_contact_points(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: return True else: @@ -113,23 +105,21 @@ def contact_point_check(grafana_url, http_get_headers, verify_ssl, client_cert, def search_dashboard(page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - url = '{0}/api/search/?type=dash-db&limit={1}&page={2}'.format( - grafana_url, limit, page) - print("search dashboard in grafana: {0}".format(url)) + url = '{0}/api/search/?type=dash-db&limit={1}&page={2}'.format(grafana_url, limit, page) + print('search dashboard in grafana: {0}'.format(url)) return send_grafana_get(url, http_get_headers, verify_ssl, client_cert, debug) def get_dashboard(board_uri, grafana_url, http_get_headers, verify_ssl, client_cert, debug): url = '{0}/api/dashboards/{1}'.format(grafana_url, board_uri) - print("query dashboard uri: {0}".format(url)) - (status_code, content) = send_grafana_get( - url, http_get_headers, verify_ssl, client_cert, debug) + print('query dashboard uri: {0}'.format(url)) + (status_code, content) = send_grafana_get(url, http_get_headers, verify_ssl, client_cert, debug) return (status_code, content) def search_library_elements(grafana_url, http_get_headers, verify_ssl, client_cert, debug): url = '{0}/api/library-elements?perPage=5000'.format(grafana_url) - print("search library-elements in grafana: {0}".format(url)) + print('search library-elements in grafana: {0}'.format(url)) return send_grafana_get(url, http_get_headers, verify_ssl, client_cert, debug) @@ -139,13 +129,14 @@ def create_library_element(library_element, grafana_url, http_post_headers, veri def delete_library_element(id_, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - return send_grafana_delete('{0}/api/library-elements/{1}'.format(grafana_url, id_), http_get_headers, - verify_ssl, client_cert) + return send_grafana_delete( + '{0}/api/library-elements/{1}'.format(grafana_url, id_), http_get_headers, verify_ssl, client_cert + ) def search_teams(grafana_url, http_get_headers, verify_ssl, client_cert, debug): url = '{0}/api/teams/search?perPage=5000'.format(grafana_url) - print("search teams in grafana: {0}".format(url)) + print('search teams in grafana: {0}'.format(url)) return send_grafana_get(url, http_get_headers, verify_ssl, client_cert, debug) @@ -155,13 +146,12 @@ def create_team(team, grafana_url, http_post_headers, verify_ssl, client_cert, d def delete_team(id_, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - return send_grafana_delete('{0}/api/teams/{1}'.format(grafana_url, id_), http_get_headers, - verify_ssl, client_cert) + return send_grafana_delete('{0}/api/teams/{1}'.format(grafana_url, id_), http_get_headers, verify_ssl, client_cert) def search_team_members(team_id, grafana_url, http_get_headers, verify_ssl, client_cert, debug): url = '{0}/api/teams/{1}/members'.format(grafana_url, team_id) - print("search team members in grafana: {0}".format(url)) + print('search team members in grafana: {0}'.format(url)) return send_grafana_get(url, http_get_headers, verify_ssl, client_cert, debug) @@ -171,18 +161,17 @@ def create_team_member(user, team_id, grafana_url, http_post_headers, verify_ssl def delete_team_member(user_id, team_id, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - return send_grafana_delete('{0}/api/teams/{1}/members/{2}'.format(grafana_url, team_id, user_id), http_get_headers, - verify_ssl, client_cert) + return send_grafana_delete( + '{0}/api/teams/{1}/members/{2}'.format(grafana_url, team_id, user_id), http_get_headers, verify_ssl, client_cert + ) def search_annotations(grafana_url, ts_from, ts_to, http_get_headers, verify_ssl, client_cert, debug): # there are two types of annotations # annotation: are user created, custom ones and can be managed via the api # alert: are created by Grafana itself, can NOT be managed by the api - url = '{0}/api/annotations?type=annotation&limit=5000&from={1}&to={2}'.format( - grafana_url, ts_from, ts_to) - (status_code, content) = send_grafana_get( - url, http_get_headers, verify_ssl, client_cert, debug) + url = '{0}/api/annotations?type=annotation&limit=5000&from={1}&to={2}'.format(grafana_url, ts_from, ts_to) + (status_code, content) = send_grafana_get(url, http_get_headers, verify_ssl, client_cert, debug) return (status_code, content) @@ -192,13 +181,14 @@ def create_annotation(annotation, grafana_url, http_post_headers, verify_ssl, cl def delete_annotation(id_, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - return send_grafana_delete('{0}/api/annotations/{1}'.format(grafana_url, id_), http_get_headers, verify_ssl, - client_cert, debug) + return send_grafana_delete( + '{0}/api/annotations/{1}'.format(grafana_url, id_), http_get_headers, verify_ssl, client_cert, debug + ) def search_alert_rules(grafana_url, http_get_headers, verify_ssl, client_cert, debug): url = '{0}/api/v1/provisioning/alert-rules'.format(grafana_url) - print("search alert rules in grafana: {0}".format(url)) + print('search alert rules in grafana: {0}'.format(url)) return send_grafana_get(url, http_get_headers, verify_ssl, client_cert, debug) @@ -224,152 +214,173 @@ def update_alert_rule(uid, alert, grafana_url, http_get_headers, verify_ssl, cli def search_alert_channels(grafana_url, http_get_headers, verify_ssl, client_cert, debug): url = '{0}/api/alert-notifications'.format(grafana_url) - print("search alert channels in grafana: {0}".format(url)) + print('search alert channels in grafana: {0}'.format(url)) return send_grafana_get(url, http_get_headers, verify_ssl, client_cert, debug) def create_alert_channel(payload, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_post('{0}/api/alert-notifications'.format(grafana_url), payload, http_post_headers, verify_ssl, - client_cert, debug) + return send_grafana_post( + '{0}/api/alert-notifications'.format(grafana_url), payload, http_post_headers, verify_ssl, client_cert, debug + ) def delete_alert_channel_by_uid(uid, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_delete('{0}/api/alert-notifications/uid/{1}'.format(grafana_url, uid), http_post_headers, - verify_ssl, client_cert, debug) + return send_grafana_delete( + '{0}/api/alert-notifications/uid/{1}'.format(grafana_url, uid), + http_post_headers, + verify_ssl, + client_cert, + debug, + ) def delete_alert_channel_by_id(id_, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_delete('{0}/api/alert-notifications/{1}'.format(grafana_url, id_), http_post_headers, - verify_ssl, client_cert, debug) + return send_grafana_delete( + '{0}/api/alert-notifications/{1}'.format(grafana_url, id_), http_post_headers, verify_ssl, client_cert, debug + ) def search_alerts(grafana_url, http_get_headers, verify_ssl, client_cert, debug): url = '{0}/api/alerts'.format(grafana_url) - (status_code, content) = send_grafana_get( - url, http_get_headers, verify_ssl, client_cert, debug) + (status_code, content) = send_grafana_get(url, http_get_headers, verify_ssl, client_cert, debug) return (status_code, content) def pause_alert(id_, grafana_url, http_post_headers, verify_ssl, client_cert, debug): url = '{0}/api/alerts/{1}/pause'.format(grafana_url, id_) payload = '{ "paused": true }' - (status_code, content) = send_grafana_post( - url, payload, http_post_headers, verify_ssl, client_cert, debug) + (status_code, content) = send_grafana_post(url, payload, http_post_headers, verify_ssl, client_cert, debug) return (status_code, content) def unpause_alert(id_, grafana_url, http_post_headers, verify_ssl, client_cert, debug): url = '{0}/api/alerts/{1}/pause'.format(grafana_url, id_) payload = '{ "paused": false }' - (status_code, content) = send_grafana_post( - url, payload, http_post_headers, verify_ssl, client_cert, debug) + (status_code, content) = send_grafana_post(url, payload, http_post_headers, verify_ssl, client_cert, debug) return (status_code, content) def delete_folder(uid, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_delete('{0}/api/folders/{1}'.format(grafana_url, uid), http_post_headers, verify_ssl, - client_cert, debug) + return send_grafana_delete( + '{0}/api/folders/{1}'.format(grafana_url, uid), http_post_headers, verify_ssl, client_cert, debug + ) def delete_snapshot(key, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_delete('{0}/api/snapshots/{1}'.format(grafana_url, key), http_post_headers, verify_ssl, - client_cert, debug) + return send_grafana_delete( + '{0}/api/snapshots/{1}'.format(grafana_url, key), http_post_headers, verify_ssl, client_cert, debug + ) def delete_dashboard_by_uid(uid, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_delete('{0}/api/dashboards/uid/{1}'.format(grafana_url, uid), http_post_headers, verify_ssl, - client_cert, debug) + return send_grafana_delete( + '{0}/api/dashboards/uid/{1}'.format(grafana_url, uid), http_post_headers, verify_ssl, client_cert, debug + ) def delete_dashboard_by_slug(slug, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_delete('{0}/api/dashboards/db/{1}'.format(grafana_url, slug), http_post_headers, verify_ssl, - client_cert, debug) + return send_grafana_delete( + '{0}/api/dashboards/db/{1}'.format(grafana_url, slug), http_post_headers, verify_ssl, client_cert, debug + ) def create_dashboard(payload, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_post('{0}/api/dashboards/db'.format(grafana_url), payload, http_post_headers, verify_ssl, - client_cert, debug) + return send_grafana_post( + '{0}/api/dashboards/db'.format(grafana_url), payload, http_post_headers, verify_ssl, client_cert, debug + ) def search_datasource(grafana_url, http_get_headers, verify_ssl, client_cert, debug): - print("search datasources in grafana:") + print('search datasources in grafana:') return send_grafana_get('{0}/api/datasources'.format(grafana_url), http_get_headers, verify_ssl, client_cert, debug) def search_snapshot(grafana_url, http_get_headers, verify_ssl, client_cert, debug): - print("search snapshots in grafana:") - return send_grafana_get('{0}/api/dashboard/snapshots'.format(grafana_url), http_get_headers, verify_ssl, client_cert, debug) + print('search snapshots in grafana:') + return send_grafana_get( + '{0}/api/dashboard/snapshots'.format(grafana_url), http_get_headers, verify_ssl, client_cert, debug + ) def get_snapshot(key, grafana_url, http_get_headers, verify_ssl, client_cert, debug): url = '{0}/api/snapshots/{1}'.format(grafana_url, key) - (status_code, content) = send_grafana_get( - url, http_get_headers, verify_ssl, client_cert, debug) + (status_code, content) = send_grafana_get(url, http_get_headers, verify_ssl, client_cert, debug) return (status_code, content) def create_snapshot(payload, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_post('{0}/api/snapshots'.format(grafana_url), payload, http_post_headers, verify_ssl, - client_cert, debug) + return send_grafana_post( + '{0}/api/snapshots'.format(grafana_url), payload, http_post_headers, verify_ssl, client_cert, debug + ) def create_datasource(payload, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_post('{0}/api/datasources'.format(grafana_url), payload, http_post_headers, verify_ssl, - client_cert, debug) + return send_grafana_post( + '{0}/api/datasources'.format(grafana_url), payload, http_post_headers, verify_ssl, client_cert, debug + ) def delete_datasource_by_uid(uid, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_delete('{0}/api/datasources/uid/{1}'.format(grafana_url, uid), http_post_headers, verify_ssl, - client_cert, debug) + return send_grafana_delete( + '{0}/api/datasources/uid/{1}'.format(grafana_url, uid), http_post_headers, verify_ssl, client_cert, debug + ) def delete_datasource_by_id(id_, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_delete('{0}/api/datasources/{1}'.format(grafana_url, id_), http_post_headers, verify_ssl, - client_cert, debug) + return send_grafana_delete( + '{0}/api/datasources/{1}'.format(grafana_url, id_), http_post_headers, verify_ssl, client_cert, debug + ) def search_folders(grafana_url, http_get_headers, verify_ssl, client_cert, debug): - print("search folder in grafana:") - return send_grafana_get('{0}/api/search/?type=dash-folder'.format(grafana_url), http_get_headers, verify_ssl, - client_cert, debug) + print('search folder in grafana:') + return send_grafana_get( + '{0}/api/search/?type=dash-folder'.format(grafana_url), http_get_headers, verify_ssl, client_cert, debug + ) def get_folder(uid, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - (status_code, content) = send_grafana_get('{0}/api/folders/{1}'.format(grafana_url, uid), http_get_headers, - verify_ssl, client_cert, debug) - print("query folder:{0}, status:{1}".format(uid, status_code)) + (status_code, content) = send_grafana_get( + '{0}/api/folders/{1}'.format(grafana_url, uid), http_get_headers, verify_ssl, client_cert, debug + ) + print('query folder:{0}, status:{1}'.format(uid, status_code)) return (status_code, content) def get_folder_permissions(uid, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - (status_code, content) = send_grafana_get('{0}/api/folders/{1}/permissions'.format(grafana_url, uid), http_get_headers, - verify_ssl, client_cert, debug) - print("query folder permissions:{0}, status:{1}".format(uid, status_code)) + (status_code, content) = send_grafana_get( + '{0}/api/folders/{1}/permissions'.format(grafana_url, uid), http_get_headers, verify_ssl, client_cert, debug + ) + print('query folder permissions:{0}, status:{1}'.format(uid, status_code)) return (status_code, content) def update_folder_permissions(payload, grafana_url, http_post_headers, verify_ssl, client_cert, debug): items = json.dumps({'items': payload}) - return send_grafana_post('{0}/api/folders/{1}/permissions'.format(grafana_url, payload[0]['uid']), items, http_post_headers, verify_ssl, client_cert, - debug) + return send_grafana_post( + '{0}/api/folders/{1}/permissions'.format(grafana_url, payload[0]['uid']), + items, + http_post_headers, + verify_ssl, + client_cert, + debug, + ) def get_folder_id(dashboard, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - folder_uid = "" + folder_uid = '' try: folder_uid = dashboard['meta']['folderUid'] - except (KeyError): - matches = re.search('dashboards\/f\/(.*)\/.*', - dashboard['meta']['folderUrl']) + except KeyError: + matches = re.search('dashboards\/f\/(.*)\/.*', dashboard['meta']['folderUrl']) if matches is not None: folder_uid = matches.group(1) else: folder_uid = '0' - if (folder_uid != ""): - print("debug: quering with uid {}".format(folder_uid)) - response = get_folder(folder_uid, grafana_url, - http_post_headers, verify_ssl, client_cert, debug) + if folder_uid != '': + print('debug: quering with uid {}'.format(folder_uid)) + response = get_folder(folder_uid, grafana_url, http_post_headers, verify_ssl, client_cert, debug) if isinstance(response[1], dict): folder_data = response[1] else: @@ -377,56 +388,72 @@ def get_folder_id(dashboard, grafana_url, http_post_headers, verify_ssl, client_ try: return folder_data['id'] - except (KeyError): + except KeyError: return 0 else: return 0 def create_folder(payload, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_post('{0}/api/folders'.format(grafana_url), payload, http_post_headers, verify_ssl, client_cert, - debug) + return send_grafana_post( + '{0}/api/folders'.format(grafana_url), payload, http_post_headers, verify_ssl, client_cert, debug + ) def get_dashboard_versions(dashboard_id, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - (status_code, content) = send_grafana_get('{0}/api/dashboards/id/{1}/versions'.format(grafana_url, dashboard_id), http_get_headers, - verify_ssl, client_cert, debug) - print("query dashboard versions: {0}, status: {1}".format( - dashboard_id, status_code)) + (status_code, content) = send_grafana_get( + '{0}/api/dashboards/id/{1}/versions'.format(grafana_url, dashboard_id), + http_get_headers, + verify_ssl, + client_cert, + debug, + ) + print('query dashboard versions: {0}, status: {1}'.format(dashboard_id, status_code)) return (status_code, content) def get_version(dashboard_id, version_number, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - (status_code, content) = send_grafana_get('{0}/api/dashboards/id/{1}/versions/{2}'.format(grafana_url, dashboard_id, version_number), http_get_headers, - verify_ssl, client_cert, debug) - print("query dashboard {0} version {1}, status: {2}".format( - dashboard_id, version_number, status_code)) + (status_code, content) = send_grafana_get( + '{0}/api/dashboards/id/{1}/versions/{2}'.format(grafana_url, dashboard_id, version_number), + http_get_headers, + verify_ssl, + client_cert, + debug, + ) + print('query dashboard {0} version {1}, status: {2}'.format(dashboard_id, version_number, status_code)) return (status_code, content) def search_orgs(grafana_url, http_get_headers, verify_ssl, client_cert, debug): - return send_grafana_get('{0}/api/orgs'.format(grafana_url), http_get_headers, verify_ssl, - client_cert, debug) + return send_grafana_get('{0}/api/orgs'.format(grafana_url), http_get_headers, verify_ssl, client_cert, debug) def get_org(id, grafana_url, http_get_headers, verify_ssl=False, client_cert=None, debug=True): - return send_grafana_get('{0}/api/orgs/{1}'.format(grafana_url, id), - http_get_headers, verify_ssl, client_cert, debug) + return send_grafana_get( + '{0}/api/orgs/{1}'.format(grafana_url, id), http_get_headers, verify_ssl, client_cert, debug + ) def create_org(payload, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_post('{0}/api/orgs'.format(grafana_url), payload, http_post_headers, verify_ssl, client_cert, - debug) + return send_grafana_post( + '{0}/api/orgs'.format(grafana_url), payload, http_post_headers, verify_ssl, client_cert, debug + ) def update_org(id, payload, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_put('{0}/api/orgs/{1}'.format(grafana_url, id), payload, http_post_headers, verify_ssl, client_cert, - debug) + return send_grafana_put( + '{0}/api/orgs/{1}'.format(grafana_url, id), payload, http_post_headers, verify_ssl, client_cert, debug + ) def search_users(page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - return send_grafana_get('{0}/api/users?perpage={1}&page={2}'.format(grafana_url, limit, page), - http_get_headers, verify_ssl, client_cert, debug) + return send_grafana_get( + '{0}/api/users?perpage={1}&page={2}'.format(grafana_url, limit, page), + http_get_headers, + verify_ssl, + client_cert, + debug, + ) def get_users(grafana_url, http_get_headers, verify_ssl, client_cert, debug): @@ -436,58 +463,91 @@ def get_users(grafana_url, http_get_headers, verify_ssl, client_cert, debug): def set_user_role(user_id, role, grafana_url, http_post_headers, verify_ssl, client_cert, debug): json_payload = json.dumps({'role': role}) url = '{0}/api/org/users/{1}'.format(grafana_url, user_id) - r = requests.patch(url, headers=http_post_headers, - data=json_payload, verify=verify_ssl, cert=client_cert) + r = requests.patch(url, headers=http_post_headers, data=json_payload, verify=verify_ssl, cert=client_cert) return (r.status_code, r.json()) def get_user(id, grafana_url, http_get_headers, verify_ssl=False, client_cert=None, debug=True): - return send_grafana_get('{0}/api/users/{1}'.format(grafana_url, id), - http_get_headers, verify_ssl, client_cert, debug) + return send_grafana_get( + '{0}/api/users/{1}'.format(grafana_url, id), http_get_headers, verify_ssl, client_cert, debug + ) def get_user_by_email_or_username(email, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - return send_grafana_get('{0}/api/users/lookup?loginOrEmail={1}'.format(grafana_url, email), http_get_headers, - verify_ssl, client_cert, debug) + return send_grafana_get( + '{0}/api/users/lookup?loginOrEmail={1}'.format(grafana_url, email), + http_get_headers, + verify_ssl, + client_cert, + debug, + ) def get_user_org(id, grafana_url, http_get_headers, verify_ssl=False, client_cert=None, debug=True): - return send_grafana_get('{0}/api/users/{1}/orgs'.format(grafana_url, id), - http_get_headers, verify_ssl, client_cert, debug) + return send_grafana_get( + '{0}/api/users/{1}/orgs'.format(grafana_url, id), http_get_headers, verify_ssl, client_cert, debug + ) def create_user(payload, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_post('{0}/api/admin/users'.format(grafana_url), payload, http_post_headers, verify_ssl, client_cert, - debug) + return send_grafana_post( + '{0}/api/admin/users'.format(grafana_url), payload, http_post_headers, verify_ssl, client_cert, debug + ) def add_user_to_org(org_id, payload, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_post('{0}/api/orgs/{1}/users'.format(grafana_url, org_id), payload, http_post_headers, verify_ssl, client_cert, - debug) + return send_grafana_post( + '{0}/api/orgs/{1}/users'.format(grafana_url, org_id), payload, http_post_headers, verify_ssl, client_cert, debug + ) def search_contact_points(grafana_url, http_get_headers, verify_ssl, client_cert, debug): - return send_grafana_get('{0}/api/v1/provisioning/contact-points'.format(grafana_url), http_get_headers, verify_ssl, client_cert, debug) + return send_grafana_get( + '{0}/api/v1/provisioning/contact-points'.format(grafana_url), http_get_headers, verify_ssl, client_cert, debug + ) def create_contact_point(json_palyload, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_post('{0}/api/v1/provisioning/contact-points'.format(grafana_url), json_palyload, http_post_headers, verify_ssl, client_cert, debug) + return send_grafana_post( + '{0}/api/v1/provisioning/contact-points'.format(grafana_url), + json_palyload, + http_post_headers, + verify_ssl, + client_cert, + debug, + ) + def update_contact_point(uid, json_palyload, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_put('{0}/api/v1/provisioning/contact-points/{1}'.format(grafana_url, uid), json_palyload, http_post_headers, verify_ssl, client_cert, debug) + return send_grafana_put( + '{0}/api/v1/provisioning/contact-points/{1}'.format(grafana_url, uid), + json_palyload, + http_post_headers, + verify_ssl, + client_cert, + debug, + ) def search_notification_policies(grafana_url, http_get_headers, verify_ssl, client_cert, debug): - return send_grafana_get('{0}/api/v1/provisioning/policies'.format(grafana_url), http_get_headers, verify_ssl, client_cert, debug) + return send_grafana_get( + '{0}/api/v1/provisioning/policies'.format(grafana_url), http_get_headers, verify_ssl, client_cert, debug + ) def update_notification_policy(json_palyload, grafana_url, http_post_headers, verify_ssl, client_cert, debug): - return send_grafana_put('{0}/api/v1/provisioning/policies'.format(grafana_url), json_palyload, http_post_headers, verify_ssl, client_cert, debug) + return send_grafana_put( + '{0}/api/v1/provisioning/policies'.format(grafana_url), + json_palyload, + http_post_headers, + verify_ssl, + client_cert, + debug, + ) def get_grafana_version(grafana_url, verify_ssl, http_get_headers): - r = requests.get('{0}/api/health'.format(grafana_url), - verify=verify_ssl, headers=http_get_headers) + r = requests.get('{0}/api/health'.format(grafana_url), verify=verify_ssl, headers=http_get_headers) if r.status_code == 200: if 'version' in r.json().keys(): version_str = r.json()['version'] @@ -499,28 +559,25 @@ def get_grafana_version(grafana_url, verify_ssl, http_get_headers): version_number = match.group(1) else: raise Exception( - "version key found but string value could not be parsed, returned respone: {0}".format(r.json)) + 'version key found but string value could not be parsed, returned respone: {0}'.format(r.json) + ) return version.parse(version_number) else: - raise KeyError( - "Unable to get version, returned respone: {0}".format(r.json)) + raise KeyError('Unable to get version, returned respone: {0}'.format(r.json)) else: - raise Exception( - "Unable to get version, returned response: {0}".format(r.status_code)) + raise Exception('Unable to get version, returned response: {0}'.format(r.status_code)) def send_grafana_get(url, http_get_headers, verify_ssl, client_cert, debug): - r = requests.get(url, headers=http_get_headers, - verify=verify_ssl, cert=client_cert) + r = requests.get(url, headers=http_get_headers, verify=verify_ssl, cert=client_cert) if debug: log_response(r) return (r.status_code, r.json()) def send_grafana_post(url, json_payload, http_post_headers, verify_ssl=False, client_cert=None, debug=True): - r = requests.post(url, headers=http_post_headers, - data=json_payload, verify=verify_ssl, cert=client_cert) + r = requests.post(url, headers=http_post_headers, data=json_payload, verify=verify_ssl, cert=client_cert) if debug: log_response(r) try: @@ -530,14 +587,12 @@ def send_grafana_post(url, json_payload, http_post_headers, verify_ssl=False, cl def send_grafana_put(url, json_payload, http_post_headers, verify_ssl=False, client_cert=None, debug=True): - r = requests.put(url, headers=http_post_headers, - data=json_payload, verify=verify_ssl, cert=client_cert) + r = requests.put(url, headers=http_post_headers, data=json_payload, verify=verify_ssl, cert=client_cert) if debug: log_response(r) return (r.status_code, r.json()) def send_grafana_delete(url, http_get_headers, verify_ssl=False, client_cert=None, debug=True): - r = requests.delete(url, headers=http_get_headers, - verify=verify_ssl, cert=client_cert) + r = requests.delete(url, headers=http_get_headers, verify=verify_ssl, cert=client_cert) return int(r.status_code) diff --git a/grafana_backup/delete.py b/grafana_backup/delete.py index da58760..325813b 100755 --- a/grafana_backup/delete.py +++ b/grafana_backup/delete.py @@ -1,13 +1,14 @@ +import sys + from grafana_backup.api_checks import main as api_checks +from grafana_backup.delete_alert_channels import main as delete_alert_channels +from grafana_backup.delete_annotations import main as delete_annotations from grafana_backup.delete_dashboards import main as delete_dashboards from grafana_backup.delete_datasources import main as delete_datasources -from grafana_backup.delete_library_elements import main as delete_library_elements from grafana_backup.delete_folders import main as delete_folders -from grafana_backup.delete_alert_channels import main as delete_alert_channels +from grafana_backup.delete_library_elements import main as delete_library_elements from grafana_backup.delete_snapshots import main as delete_snapshots -from grafana_backup.delete_annotations import main as delete_annotations from grafana_backup.delete_team_members import main as delete_team_members -import sys def main(args, settings): @@ -15,21 +16,22 @@ def main(args, settings): # By default, teams should not be deleted. Sinces teams don't have unique ids across instances, they would be # recreated with different ids, therefore loosing references to folder permissions and team members. - delete_functions = {'dashboards': delete_dashboards, - 'datasources': delete_datasources, - 'folders': delete_folders, - 'alert-channels': delete_alert_channels, - 'snapshots': delete_snapshots, - 'annotations': delete_annotations, - 'library-elements': delete_library_elements, - 'team-members': delete_team_members} - - (status, json_resp, dashboard_uid_support, - datasource_uid_support, paging_support) = api_checks(settings) + delete_functions = { + 'dashboards': delete_dashboards, + 'datasources': delete_datasources, + 'folders': delete_folders, + 'alert-channels': delete_alert_channels, + 'snapshots': delete_snapshots, + 'annotations': delete_annotations, + 'library-elements': delete_library_elements, + 'team-members': delete_team_members, + } + + (status, json_resp, dashboard_uid_support, datasource_uid_support, paging_support) = api_checks(settings) # Do not continue if API is unavailable or token is not valid if not status == 200: - print("server status is not ok: {0}".format(json_resp)) + print('server status is not ok: {0}'.format(json_resp)) sys.exit(1) settings.update({'DASHBOARD_UID_SUPPORT': dashboard_uid_support}) diff --git a/grafana_backup/delete_alert_channels.py b/grafana_backup/delete_alert_channels.py index 37a6f15..be9638e 100644 --- a/grafana_backup/delete_alert_channels.py +++ b/grafana_backup/delete_alert_channels.py @@ -1,7 +1,5 @@ -from grafana_backup.dashboardApi import search_alert_channels -from grafana_backup.dashboardApi import delete_alert_channel_by_uid -from grafana_backup.dashboardApi import delete_alert_channel_by_id -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line +from grafana_backup.commons import print_horizontal_line, to_python2_and_3_compatible_string +from grafana_backup.dashboardApi import delete_alert_channel_by_id, delete_alert_channel_by_uid, search_alert_channels def main(args, settings): @@ -13,8 +11,9 @@ def main(args, settings): pretty_print = settings.get('PRETTY_PRINT') alert_channels = get_all_alert_channels_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, debug) - get_individual_alert_channel_and_delete(alert_channels, pretty_print, grafana_url, http_get_headers, verify_ssl, - client_cert, debug) + get_individual_alert_channel_and_delete( + alert_channels, pretty_print, grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) print_horizontal_line() @@ -22,30 +21,33 @@ def get_all_alert_channels_in_grafana(grafana_url, http_get_headers, verify_ssl, (status, content) = search_alert_channels(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: channels = content - print("There are {0} channels:".format(len(channels))) + print('There are {0} channels:'.format(len(channels))) for channel in channels: - print("name: {0}".format(to_python2_and_3_compatible_string(channel['name']))) + print('name: {0}'.format(to_python2_and_3_compatible_string(channel['name']))) return channels else: - print("query alert channels failed, status: {0}, msg: {1}".format(status, content)) + print('query alert channels failed, status: {0}, msg: {1}'.format(status, content)) return [] -def get_individual_alert_channel_and_delete(channels, pretty_print, grafana_url, http_get_headers, verify_ssl, - client_cert, debug): +def get_individual_alert_channel_and_delete( + channels, pretty_print, grafana_url, http_get_headers, verify_ssl, client_cert, debug +): if channels: for channel in channels: status = 0 if 'uid' in channel: - status = delete_alert_channel_by_uid(channel['uid'], grafana_url, http_get_headers, verify_ssl, - client_cert, debug) + status = delete_alert_channel_by_uid( + channel['uid'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) else: - status = delete_alert_channel_by_id(channel['id'], grafana_url, http_get_headers, verify_ssl, - client_cert, debug) + status = delete_alert_channel_by_id( + channel['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) channel_name = to_python2_and_3_compatible_string(channel['name']) if status == 200: - print("alert_channel:{0} is deleted".format(channel_name)) + print('alert_channel:{0} is deleted'.format(channel_name)) else: - print("deleting alert_channel {0} failed with {1}".format(channel_name, status)) + print('deleting alert_channel {0} failed with {1}'.format(channel_name, status)) diff --git a/grafana_backup/delete_annotations.py b/grafana_backup/delete_annotations.py index debafdb..81c714b 100644 --- a/grafana_backup/delete_annotations.py +++ b/grafana_backup/delete_annotations.py @@ -1,6 +1,7 @@ import time -from grafana_backup.dashboardApi import search_annotations, delete_annotation + from grafana_backup.commons import print_horizontal_line +from grafana_backup.dashboardApi import delete_annotation, search_annotations def main(args, settings): @@ -21,22 +22,29 @@ def get_all_annotations_and_delete(grafana_url, http_get_headers, verify_ssl, cl ts_to = now ts_from = now - one_month_in_ms - thirteen_months_retention = (now - (13 * one_month_in_ms)) + thirteen_months_retention = now - (13 * one_month_in_ms) while ts_from > thirteen_months_retention: - status_code_and_content = search_annotations(grafana_url, ts_from, ts_to, http_get_headers, verify_ssl, client_cert, debug) + status_code_and_content = search_annotations( + grafana_url, ts_from, ts_to, http_get_headers, verify_ssl, client_cert, debug + ) if status_code_and_content[0] == 200: annotations = status_code_and_content[1] - print("There are {0} annotations:".format(len(annotations))) + print('There are {0} annotations:'.format(len(annotations))) for annotation in annotations: - status = delete_annotation(annotation['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) + status = delete_annotation( + annotation['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) if status == 200: - print("annotation:{0} is deleted".format(annotation['id'])) + print('annotation:{0} is deleted'.format(annotation['id'])) else: - print("deleting of annotation {0} failed with: {1}".format(annotation['id'], status)) + print('deleting of annotation {0} failed with: {1}'.format(annotation['id'], status)) else: - print("query annotation failed, status: {0}, msg: {1}".format(status_code_and_content[0], - status_code_and_content[1])) + print( + 'query annotation failed, status: {0}, msg: {1}'.format( + status_code_and_content[0], status_code_and_content[1] + ) + ) ts_to = ts_from ts_from = ts_from - one_month_in_ms diff --git a/grafana_backup/delete_dashboards.py b/grafana_backup/delete_dashboards.py index e22e35c..a65705a 100644 --- a/grafana_backup/delete_dashboards.py +++ b/grafana_backup/delete_dashboards.py @@ -1,5 +1,5 @@ -from grafana_backup.dashboardApi import search_dashboard, delete_dashboard_by_uid, delete_dashboard_by_slug -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line +from grafana_backup.commons import print_horizontal_line, to_python2_and_3_compatible_string +from grafana_backup.dashboardApi import delete_dashboard_by_slug, delete_dashboard_by_uid, search_dashboard def main(args, settings): @@ -14,62 +14,75 @@ def main(args, settings): paging_support = settings.get('PAGING_SUPPORT') if paging_support: - delete_dashboards_above_Ver6_2(grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support) + delete_dashboards_above_Ver6_2( + grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support + ) else: - delete_dashboards(limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support) + delete_dashboards( + limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support + ) def get_all_dashboards_in_grafana(page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - (status, content) = search_dashboard(page, - limit, - grafana_url, - http_get_headers, - verify_ssl, client_cert, - debug) + (status, content) = search_dashboard(page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: dashboards = content - print("There are {0} dashboards:".format(len(dashboards))) + print('There are {0} dashboards:'.format(len(dashboards))) for board in dashboards: print('name: {0}'.format(to_python2_and_3_compatible_string(board['title']))) return dashboards else: - print("get dashboards failed, status: {0}, msg: {1}".format(status, content)) + print('get dashboards failed, status: {0}, msg: {1}'.format(status, content)) return [] -def get_individual_dashboard_and_delete(dashboards, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support): +def get_individual_dashboard_and_delete( + dashboards, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support +): if dashboards: for board in dashboards: if uid_support: - status = delete_dashboard_by_uid(board['uid'], grafana_url, http_get_headers, verify_ssl, client_cert, - debug) + status = delete_dashboard_by_uid( + board['uid'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) else: - status = delete_dashboard_by_slug(board['slug'], grafana_url, http_get_headers, verify_ssl, client_cert, - debug) + status = delete_dashboard_by_slug( + board['slug'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) if status == 200: - print("deleted dashboard {0}".format(board['title'])) + print('deleted dashboard {0}'.format(board['title'])) else: - print("got {0} when trying to delete board {1}".format(status, board['title'])) + print('got {0} when trying to delete board {1}'.format(status, board['title'])) -def delete_dashboards_above_Ver6_2(grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support): +def delete_dashboards_above_Ver6_2( + grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support +): limit = 5000 # limit is 5000 above V6.2+ current_page = 1 while True: - dashboards = get_all_dashboards_in_grafana(current_page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug) + dashboards = get_all_dashboards_in_grafana( + current_page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) print_horizontal_line() if len(dashboards) == 0: break else: current_page += 1 - get_individual_dashboard_and_delete(dashboards, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support) + get_individual_dashboard_and_delete( + dashboards, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support + ) print_horizontal_line() def delete_dashboards(limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support): current_page = 1 - dashboards = get_all_dashboards_in_grafana(current_page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug) + dashboards = get_all_dashboards_in_grafana( + current_page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) print_horizontal_line() - get_individual_dashboard_and_delete(dashboards, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support) + get_individual_dashboard_and_delete( + dashboards, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support + ) print_horizontal_line() diff --git a/grafana_backup/delete_datasources.py b/grafana_backup/delete_datasources.py index dacdd1c..136533e 100644 --- a/grafana_backup/delete_datasources.py +++ b/grafana_backup/delete_datasources.py @@ -1,5 +1,5 @@ -from grafana_backup.dashboardApi import search_datasource, delete_datasource_by_uid, delete_datasource_by_id from grafana_backup.commons import print_horizontal_line +from grafana_backup.dashboardApi import delete_datasource_by_id, delete_datasource_by_uid, search_datasource def main(args, settings): @@ -11,26 +11,37 @@ def main(args, settings): pretty_print = settings.get('PRETTY_PRINT') http_get_headers = settings.get('HTTP_POST_HEADERS') - get_all_datasources_and_delete(grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support) + get_all_datasources_and_delete( + grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support + ) print_horizontal_line() -def get_all_datasources_and_delete(grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support): +def get_all_datasources_and_delete( + grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support +): status_code_and_content = search_datasource(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status_code_and_content[0] == 200: datasources = status_code_and_content[1] - print("There are {0} datasources:".format(len(datasources))) + print('There are {0} datasources:'.format(len(datasources))) for datasource in datasources: print(datasource) if uid_support: - status = delete_datasource_by_uid(datasource['uid'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) + status = delete_datasource_by_uid( + datasource['uid'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) else: - status = delete_datasource_by_id(datasource['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) + status = delete_datasource_by_id( + datasource['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) if status == 200: - print("datasource:{0} is deleted".format(datasource['name'])) + print('datasource:{0} is deleted'.format(datasource['name'])) else: - print("deleting of datasource {0} failed with: {1}".format(datasource['name'], status)) + print('deleting of datasource {0} failed with: {1}'.format(datasource['name'], status)) else: - print("query datasource failed, status: {0}, msg: {1}".format(status_code_and_content[0], - status_code_and_content[1])) + print( + 'query datasource failed, status: {0}, msg: {1}'.format( + status_code_and_content[0], status_code_and_content[1] + ) + ) diff --git a/grafana_backup/delete_folders.py b/grafana_backup/delete_folders.py index 509b9b3..ee49016 100644 --- a/grafana_backup/delete_folders.py +++ b/grafana_backup/delete_folders.py @@ -1,5 +1,5 @@ -from grafana_backup.dashboardApi import search_folders, delete_folder -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line +from grafana_backup.commons import print_horizontal_line, to_python2_and_3_compatible_string +from grafana_backup.dashboardApi import delete_folder, search_folders def main(args, settings): @@ -13,7 +13,9 @@ def main(args, settings): folders = get_all_folders_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, debug) print_horizontal_line() - get_individual_folder_setting_and_save(folders, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support) + get_individual_folder_setting_and_save( + folders, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support + ) print_horizontal_line() @@ -23,20 +25,22 @@ def get_all_folders_in_grafana(grafana_url, http_get_headers, verify_ssl, client content = status_and_content_of_all_folders[1] if status == 200: folders = content - print("There are {0} folders:".format(len(content))) + print('There are {0} folders:'.format(len(content))) for folder in folders: - print("name: {0}".format(to_python2_and_3_compatible_string(folder['title']))) + print('name: {0}'.format(to_python2_and_3_compatible_string(folder['title']))) return folders else: - print("get folders failed, status: {0}, msg: {1}".format(status, content)) + print('get folders failed, status: {0}, msg: {1}'.format(status, content)) return [] -def get_individual_folder_setting_and_save(folders, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support): +def get_individual_folder_setting_and_save( + folders, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support +): for folder in folders: status = delete_folder(folder['uid'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: - print("deleted folder {0}".format(folder)) + print('deleted folder {0}'.format(folder)) else: - print("failed to delete folder {0} with {1}".format(folder, status)) + print('failed to delete folder {0} with {1}'.format(folder, status)) diff --git a/grafana_backup/delete_library_elements.py b/grafana_backup/delete_library_elements.py index 87c60a1..a30492d 100644 --- a/grafana_backup/delete_library_elements.py +++ b/grafana_backup/delete_library_elements.py @@ -1,6 +1,5 @@ -from grafana_backup.dashboardApi import search_library_elements -from grafana_backup.dashboardApi import delete_library_element -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line +from grafana_backup.commons import print_horizontal_line, to_python2_and_3_compatible_string +from grafana_backup.dashboardApi import delete_library_element, search_library_elements def main(args, settings): @@ -11,10 +10,12 @@ def main(args, settings): debug = settings.get('DEBUG') pretty_print = settings.get('PRETTY_PRINT') - library_elements = get_all_library_elements_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, - debug) - get_individual_library_element_and_delete(library_elements, pretty_print, grafana_url, http_get_headers, verify_ssl, - client_cert, debug) + library_elements = get_all_library_elements_in_grafana( + grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) + get_individual_library_element_and_delete( + library_elements, pretty_print, grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) print_horizontal_line() @@ -22,23 +23,25 @@ def get_all_library_elements_in_grafana(grafana_url, http_get_headers, verify_ss (status, content) = search_library_elements(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: library_elements = content['result']['elements'] - print("There are {0} library elements:".format(len(library_elements))) + print('There are {0} library elements:'.format(len(library_elements))) for library_element in library_elements: - print("name: {0}".format(to_python2_and_3_compatible_string(library_element['name']))) + print('name: {0}'.format(to_python2_and_3_compatible_string(library_element['name']))) return library_elements else: - print("query library elements failed, status: {0}, msg: {1}".format(status, content)) + print('query library elements failed, status: {0}, msg: {1}'.format(status, content)) return [] -def get_individual_library_element_and_delete(library_elements, pretty_print, grafana_url, http_get_headers, verify_ssl, - client_cert, debug): +def get_individual_library_element_and_delete( + library_elements, pretty_print, grafana_url, http_get_headers, verify_ssl, client_cert, debug +): if library_elements: for library_element in library_elements: - status = delete_library_element(library_element['uid'], grafana_url, http_get_headers, verify_ssl, - client_cert, debug) + status = delete_library_element( + library_element['uid'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) library_element_name = to_python2_and_3_compatible_string(library_element['name']) if status == 200: - print("library_element:{0} is deleted".format(library_element_name)) + print('library_element:{0} is deleted'.format(library_element_name)) else: - print("deleting library_element {0} failed with {1}".format(library_element_name, status)) + print('deleting library_element {0} failed with {1}'.format(library_element_name, status)) diff --git a/grafana_backup/delete_snapshots.py b/grafana_backup/delete_snapshots.py index 440254e..beab8ce 100644 --- a/grafana_backup/delete_snapshots.py +++ b/grafana_backup/delete_snapshots.py @@ -1,5 +1,5 @@ -from grafana_backup.dashboardApi import search_snapshot, delete_snapshot from grafana_backup.commons import print_horizontal_line +from grafana_backup.dashboardApi import delete_snapshot, search_snapshot def main(args, settings): @@ -18,16 +18,19 @@ def get_all_snapshots_and_delete(grafana_url, http_get_headers, verify_ssl, clie status_code_and_content = search_snapshot(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status_code_and_content[0] == 200: snapshots = status_code_and_content[1] - print("There are {0} snapshots:".format(len(snapshots))) + print('There are {0} snapshots:'.format(len(snapshots))) for snapshot in snapshots: print(snapshot) status = delete_snapshot(snapshot['key'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: - print("deleted snapshot {0}".format(snapshot['name'])) + print('deleted snapshot {0}'.format(snapshot['name'])) else: - print("failed to delete snapshot {0}, with {1}".format(snapshot['name'], status)) + print('failed to delete snapshot {0}, with {1}'.format(snapshot['name'], status)) else: - print("query snapshot failed, status: {0}, msg: {1}".format(status_code_and_content[0], - status_code_and_content[1])) + print( + 'query snapshot failed, status: {0}, msg: {1}'.format( + status_code_and_content[0], status_code_and_content[1] + ) + ) diff --git a/grafana_backup/delete_team_members.py b/grafana_backup/delete_team_members.py index 3b03317..55e6e99 100644 --- a/grafana_backup/delete_team_members.py +++ b/grafana_backup/delete_team_members.py @@ -1,5 +1,5 @@ -from grafana_backup.dashboardApi import search_teams, delete_team_member, search_team_members -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line +from grafana_backup.commons import print_horizontal_line, to_python2_and_3_compatible_string +from grafana_backup.dashboardApi import delete_team_member, search_team_members, search_teams def main(args, settings): @@ -10,10 +10,10 @@ def main(args, settings): debug = settings.get('DEBUG') pretty_print = settings.get('PRETTY_PRINT') - teams = get_all_teams_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, - debug) - get_individual_team_member_and_delete(teams, pretty_print, grafana_url, http_get_headers, verify_ssl, - client_cert, debug) + teams = get_all_teams_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, debug) + get_individual_team_member_and_delete( + teams, pretty_print, grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) print_horizontal_line() @@ -21,12 +21,12 @@ def get_all_teams_in_grafana(grafana_url, http_get_headers, verify_ssl, client_c (status, content) = search_teams(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: teams = content['teams'] - print("There are {0} teams:".format(len(teams))) + print('There are {0} teams:'.format(len(teams))) for team in teams: - print("name: {0}".format(to_python2_and_3_compatible_string(team['name']))) + print('name: {0}'.format(to_python2_and_3_compatible_string(team['name']))) return teams else: - print("query teams failed, status: {0}, msg: {1}".format(status, content)) + print('query teams failed, status: {0}, msg: {1}'.format(status, content)) return [] @@ -34,25 +34,34 @@ def get_team_members_in_grafana(team_id, grafana_url, http_get_headers, verify_s (status, content) = search_team_members(team_id, grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: team_members = content - print("There are {0} team members in team {1}:".format(len(team_members), team_id)) + print('There are {0} team members in team {1}:'.format(len(team_members), team_id)) for team_member in team_members: - print("name: {0}".format(to_python2_and_3_compatible_string(team_member['name']))) + print('name: {0}'.format(to_python2_and_3_compatible_string(team_member['name']))) return team_members else: - print("query team members failed, status: {0}, msg: {1}".format(status, content)) + print('query team members failed, status: {0}, msg: {1}'.format(status, content)) return [] -def get_individual_team_member_and_delete(teams, pretty_print, grafana_url, http_get_headers, verify_ssl, - client_cert, debug): +def get_individual_team_member_and_delete( + teams, pretty_print, grafana_url, http_get_headers, verify_ssl, client_cert, debug +): if teams: for team in teams: - for team_member in get_team_members_in_grafana(team['id'], grafana_url, http_get_headers, verify_ssl, - client_cert, debug): - status = delete_team_member(team_member['userId'], team_member['teamId'], grafana_url, http_get_headers, verify_ssl, - client_cert, debug) + for team_member in get_team_members_in_grafana( + team['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ): + status = delete_team_member( + team_member['userId'], + team_member['teamId'], + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + ) team_member_name = to_python2_and_3_compatible_string(team_member['name']) if status == 200: - print("team member:{0} is deleted".format(team_member_name)) + print('team member:{0} is deleted'.format(team_member_name)) else: - print("deleting team member {0} failed with {1}".format(team_member_name, status)) + print('deleting team member {0} failed with {1}'.format(team_member_name, status)) diff --git a/grafana_backup/delete_teams.py b/grafana_backup/delete_teams.py index 5a043a0..ea762ce 100644 --- a/grafana_backup/delete_teams.py +++ b/grafana_backup/delete_teams.py @@ -1,6 +1,5 @@ -from grafana_backup.dashboardApi import search_teams -from grafana_backup.dashboardApi import delete_team -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line +from grafana_backup.commons import print_horizontal_line, to_python2_and_3_compatible_string +from grafana_backup.dashboardApi import delete_team, search_teams def main(args, settings): @@ -11,10 +10,8 @@ def main(args, settings): debug = settings.get('DEBUG') pretty_print = settings.get('PRETTY_PRINT') - teams = get_all_teams_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, - debug) - get_individual_team_and_delete(teams, pretty_print, grafana_url, http_get_headers, verify_ssl, - client_cert, debug) + teams = get_all_teams_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, debug) + get_individual_team_and_delete(teams, pretty_print, grafana_url, http_get_headers, verify_ssl, client_cert, debug) print_horizontal_line() @@ -22,23 +19,21 @@ def get_all_teams_in_grafana(grafana_url, http_get_headers, verify_ssl, client_c (status, content) = search_teams(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: teams = content['teams'] - print("There are {0} teams:".format(len(teams))) + print('There are {0} teams:'.format(len(teams))) for team in teams: - print("name: {0}".format(to_python2_and_3_compatible_string(team['name']))) + print('name: {0}'.format(to_python2_and_3_compatible_string(team['name']))) return teams else: - print("query teams failed, status: {0}, msg: {1}".format(status, content)) + print('query teams failed, status: {0}, msg: {1}'.format(status, content)) return [] -def get_individual_team_and_delete(teams, pretty_print, grafana_url, http_get_headers, verify_ssl, - client_cert, debug): +def get_individual_team_and_delete(teams, pretty_print, grafana_url, http_get_headers, verify_ssl, client_cert, debug): if teams: for team in teams: - status = delete_team(team['id'], grafana_url, http_get_headers, verify_ssl, - client_cert, debug) + status = delete_team(team['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) team_name = to_python2_and_3_compatible_string(team['name']) if status == 200: - print("team:{0} is deleted".format(team_name)) + print('team:{0} is deleted'.format(team_name)) else: - print("deleting team {0} failed with {1}".format(team_name, status)) + print('deleting team {0} failed with {1}'.format(team_name, status)) diff --git a/grafana_backup/gcs_download.py b/grafana_backup/gcs_download.py index 30466ba..ac75f77 100644 --- a/grafana_backup/gcs_download.py +++ b/grafana_backup/gcs_download.py @@ -1,5 +1,6 @@ -from google import api_core import io + +from google import api_core from google.cloud import storage @@ -21,16 +22,16 @@ def main(args, settings): gcs_data = io.BytesIO(blob.download_as_bytes()) print("Download from GCS: '{0}' was successful".format(bucket_name)) except FileNotFoundError: # noqa: F821 - print("The file: {0} was not found".format(arg_archive_file)) + print('The file: {0} was not found'.format(arg_archive_file)) return False except api_core.exceptions.Forbidden as e: - print("Permission denied: {0}, please grant `Storage Admin` to service account you used".format(str(e))) + print('Permission denied: {0}, please grant `Storage Admin` to service account you used'.format(str(e))) return False except api_core.exceptions.NotFound: print("The file: {0} or gcs bucket: {1} doesn't exist".format(gcs_blob_name, bucket_name)) return False except Exception as e: - print("Exception: {0}".format(str(e))) + print('Exception: {0}'.format(str(e))) return False return gcs_data diff --git a/grafana_backup/gcs_upload.py b/grafana_backup/gcs_upload.py index 24bafce..f9456f1 100644 --- a/grafana_backup/gcs_upload.py +++ b/grafana_backup/gcs_upload.py @@ -20,18 +20,18 @@ def main(args, settings): blob = bucket.blob(gcs_blob_name) blob.upload_from_filename(archive_file) - print("Upload to gcs: was successful") + print('Upload to gcs: was successful') except FileNotFoundError: # noqa: F821 - print("The file: {0} was not found".format(archive_file)) + print('The file: {0} was not found'.format(archive_file)) return False except api_core.exceptions.Forbidden as e: - print("Permission denied: {0}, please grant `Storage Admin` to service account you used".format(str(e))) + print('Permission denied: {0}, please grant `Storage Admin` to service account you used'.format(str(e))) return False except api_core.exceptions.NotFound: print("The gcs bucket: {0} doesn't exist".format(bucket_name)) return False except Exception as e: - print("Exception: {0}".format(str(e))) + print('Exception: {0}'.format(str(e))) return False return True diff --git a/grafana_backup/grafanaSettings.py b/grafana_backup/grafanaSettings.py index a7d97d2..486a21d 100755 --- a/grafana_backup/grafanaSettings.py +++ b/grafana_backup/grafanaSettings.py @@ -2,6 +2,7 @@ import json import os from datetime import datetime + from grafana_backup.commons import load_config @@ -111,14 +112,17 @@ def main(config_path): UID_DASHBOARD_SLUG_SUFFIX = os.getenv('UID_DASHBOARD_SLUG_SUFFIX', uid_dashboard_slug_suffix) if isinstance(UID_DASHBOARD_SLUG_SUFFIX, str): - UID_DASHBOARD_SLUG_SUFFIX = json.loads(UID_DASHBOARD_SLUG_SUFFIX.lower()) # convert environment variable string to bool + UID_DASHBOARD_SLUG_SUFFIX = json.loads( + UID_DASHBOARD_SLUG_SUFFIX.lower() + ) # convert environment variable string to bool PRETTY_PRINT = os.getenv('PRETTY_PRINT', pretty_print) if isinstance(PRETTY_PRINT, str): PRETTY_PRINT = json.loads(PRETTY_PRINT.lower()) # convert environment variable string to bool EXTRA_HEADERS = dict( - h.split(':') for h in os.getenv('GRAFANA_HEADERS', '').split(',') if 'GRAFANA_HEADERS' in os.environ) + h.split(':') for h in os.getenv('GRAFANA_HEADERS', '').split(',') if 'GRAFANA_HEADERS' in os.environ + ) if TOKEN: HTTP_GET_HEADERS = {'Authorization': 'Bearer ' + TOKEN} @@ -139,9 +143,9 @@ def main(config_path): config_dict['GRAFANA_ADMIN_PASSWORD'] = ADMIN_PASSWORD if not GRAFANA_BASIC_AUTH and (ADMIN_ACCOUNT and ADMIN_PASSWORD): - GRAFANA_BASIC_AUTH = base64.b64encode( - "{0}:{1}".format(ADMIN_ACCOUNT, ADMIN_PASSWORD).encode('utf8') - ).decode('utf8') + GRAFANA_BASIC_AUTH = base64.b64encode('{0}:{1}'.format(ADMIN_ACCOUNT, ADMIN_PASSWORD).encode('utf8')).decode( + 'utf8' + ) if GRAFANA_BASIC_AUTH: HTTP_GET_HEADERS_BASIC_AUTH = HTTP_GET_HEADERS.copy() diff --git a/grafana_backup/influx.py b/grafana_backup/influx.py index f087ac6..7ccec70 100644 --- a/grafana_backup/influx.py +++ b/grafana_backup/influx.py @@ -1,7 +1,8 @@ import datetime -import influxdb import sys +import influxdb + def main(args, settings): influxdb_measurement = settings.get('INFLUXDB_MEASUREMENT') @@ -19,19 +20,21 @@ def main(args, settings): password=influxdb_password, database=influxdb_database, ssl=False, - verify_ssl=False + verify_ssl=False, ) try: - result = influx.write_points([{ - "measurement": influxdb_measurement, - "time": datetime.datetime.now(datetime.timezone.utc).isoformat(), - "fields": { - "backed_up": True - } - }]) + result = influx.write_points( + [ + { + 'measurement': influxdb_measurement, + 'time': datetime.datetime.now(datetime.timezone.utc).isoformat(), + 'fields': {'backed_up': True}, + } + ] + ) if result is True: - print("InfluxDB metrics written successfully.") + print('InfluxDB metrics written successfully.') except Exception as e: print('InfluxDB exception: \n{0}'.format(str(e))) sys.exit(1) diff --git a/grafana_backup/make_users_viewers.py b/grafana_backup/make_users_viewers.py index 8f1ca50..fff27f1 100644 --- a/grafana_backup/make_users_viewers.py +++ b/grafana_backup/make_users_viewers.py @@ -1,8 +1,9 @@ import os import sys -from grafana_backup.commons import save_json + from grafana_backup.api_checks import main as api_checks -from grafana_backup.dashboardApi import set_user_role, get_users +from grafana_backup.commons import save_json +from grafana_backup.dashboardApi import get_users, set_user_role def main(args, settings): @@ -10,7 +11,7 @@ def main(args, settings): # Do not continue if API is unavailable or token is not valid if not status == 200: - print("server status is not ok: {0}".format(json_resp)) + print('server status is not ok: {0}'.format(json_resp)) sys.exit(1) settings.update({'UID_SUPPORT': uid_support}) @@ -30,16 +31,18 @@ def main(args, settings): os.makedirs(folder_path) users = get_all_users(grafana_url, http_post_headers, verify_ssl, client_cert, debug) - file_path = save_json("users.json", users, folder_path, 'users', pretty_print) - print("users have been saved to {0}".format(file_path)) + file_path = save_json('users.json', users, folder_path, 'users', pretty_print) + print('users have been saved to {0}'.format(file_path)) for user in users: if user['role'] != 'Admin': - (status, content) = set_user_role(user['userId'], 'Viewer', grafana_url, http_post_headers, verify_ssl, client_cert, debug) - print("changed user {0} to Viewer".format(user['login'])) + (status, content) = set_user_role( + user['userId'], 'Viewer', grafana_url, http_post_headers, verify_ssl, client_cert, debug + ) + print('changed user {0} to Viewer'.format(user['login'])) if status != 200: - print("changing role of user {0} failed with {1}".format(user['login'], status)) + print('changing role of user {0} failed with {1}'.format(user['login'], status)) def get_all_users(grafana_url, http_post_headers, verify_ssl, client_cert, debug): @@ -47,5 +50,5 @@ def get_all_users(grafana_url, http_post_headers, verify_ssl, client_cert, debug if status_code == 200: return content else: - print("got status {0} when trying to get users".format(status_code)) + print('got status {0} when trying to get users'.format(status_code)) exit(1) diff --git a/grafana_backup/pause_alerts.py b/grafana_backup/pause_alerts.py index 10ef2f1..b7b3d6c 100755 --- a/grafana_backup/pause_alerts.py +++ b/grafana_backup/pause_alerts.py @@ -1,8 +1,9 @@ import os import sys -from grafana_backup.commons import save_json + from grafana_backup.api_checks import main as api_checks -from grafana_backup.dashboardApi import search_alerts, pause_alert +from grafana_backup.commons import save_json +from grafana_backup.dashboardApi import pause_alert, search_alerts def main(args, settings): @@ -10,7 +11,7 @@ def main(args, settings): # Do not continue if API is unavailable or token is not valid if not status == 200: - print("server status is not ok: {0}".format(json_resp)) + print('server status is not ok: {0}'.format(json_resp)) sys.exit(1) settings.update({'DASHBOARD_UID_SUPPORT': dashboard_uid_support}) @@ -31,13 +32,13 @@ def main(args, settings): os.makedirs(folder_path) alerts = get_all_alerts(grafana_url, http_get_headers, verify_ssl, client_cert, debug) - file_path = save_json("alerts.json", alerts, folder_path, 'alerts', pretty_print) - print("alerts have been saved to {0}".format(file_path)) + file_path = save_json('alerts.json', alerts, folder_path, 'alerts', pretty_print) + print('alerts have been saved to {0}'.format(file_path)) for alert in alerts: (status, content) = pause_alert(alert['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status != 200: - print("pausing of alert {0} failed with {1}".format(alert['name'], status)) + print('pausing of alert {0} failed with {1}'.format(alert['name'], status)) def get_all_alerts(grafana_url, http_get_headers, verify_ssl, client_cert, debug): @@ -45,5 +46,5 @@ def get_all_alerts(grafana_url, http_get_headers, verify_ssl, client_cert, debug if status_code == 200: return content else: - print("got status {0} when trying to get alerts".format(status_code)) + print('got status {0} when trying to get alerts'.format(status_code)) exit(1) diff --git a/grafana_backup/restore.py b/grafana_backup/restore.py index cc805e4..c7ebd6f 100755 --- a/grafana_backup/restore.py +++ b/grafana_backup/restore.py @@ -1,30 +1,30 @@ -from grafana_backup.create_org import main as create_org +import collections +import fnmatch +import os +import shutil +import sys +import tarfile +import tempfile +from glob import glob + 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.azure_storage_download import main as azure_storage_download from grafana_backup.create_alert_channel import main as create_alert_channel from grafana_backup.create_alert_rule import main as create_alert_rule -from grafana_backup.create_user import main as create_user -from grafana_backup.create_snapshot import main as create_snapshot from grafana_backup.create_annotation import main as create_annotation +from grafana_backup.create_contact_point import main as create_contact_point +from grafana_backup.create_dashboard import main as create_dashboard +from grafana_backup.create_datasource import main as create_datasource +from grafana_backup.create_folder import main as create_folder +from grafana_backup.create_library_element import main as create_library_element +from grafana_backup.create_org import main as create_org +from grafana_backup.create_snapshot import main as create_snapshot from grafana_backup.create_team import main as create_team from grafana_backup.create_team_member import main as create_team_member -from grafana_backup.create_library_element import main as create_library_element -from grafana_backup.create_contact_point import main as create_contact_point -from grafana_backup.update_notification_policy import main as update_notification_policy -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.create_user import main as create_user from grafana_backup.gcs_download import main as gcs_download -from glob import glob -import sys -import tarfile -import tempfile -import os -import shutil -import fnmatch -import collections +from grafana_backup.s3_download import main as s3_download +from grafana_backup.update_folder_permissions import main as update_folder_permissions def main(args, settings): @@ -41,8 +41,9 @@ def open_compressed_backup(compressed_backup): azure_storage_container_name = settings.get('AZURE_STORAGE_CONTAINER_NAME') gcs_bucket_name = settings.get('GCS_BUCKET_NAME') - (status, json_resp, dashboard_uid_support, datasource_uid_support, - paging_support, contact_point_support) = api_checks(settings) + (status, json_resp, dashboard_uid_support, datasource_uid_support, paging_support, contact_point_support) = ( + api_checks(settings) + ) settings.update({'CONTACT_POINT_SUPPORT': contact_point_support}) # Do not continue if API is unavailable or token is not valid @@ -97,7 +98,8 @@ def open_compressed_backup(compressed_backup): restore_functions['folder_permission'] = update_folder_permissions restore_functions['alert_rule'] = create_alert_rule restore_functions['contact_point'] = create_contact_point - # There are some issues of notification policy restore api, it will lock the notification policy page and cannot be edited. + # There are issues with notification policy restore API - it locks the + # notification policy page and prevents editing. # restore_functions['notification_policys'] = update_notification_policy if sys.version_info >= (3,): @@ -113,14 +115,14 @@ def open_compressed_backup(compressed_backup): try: shutil.rmtree(tmpdir) except OSError as e: - print("Error: %s : %s" % (tmpdir, e.strerror)) + print('Error: %s : %s' % (tmpdir, e.strerror)) def restore_components(args, settings, restore_functions, tmpdir): arg_components = args.get('--components', []) if arg_components: - arg_components_list = arg_components.replace("-", "_").split(',') + arg_components_list = arg_components.replace('-', '_').split(',') # Restore only the components that provided via an argument # but must also exist in extracted archive diff --git a/grafana_backup/restore_user_permissions.py b/grafana_backup/restore_user_permissions.py index f37822f..77897c8 100755 --- a/grafana_backup/restore_user_permissions.py +++ b/grafana_backup/restore_user_permissions.py @@ -1,12 +1,13 @@ -import sys import json +import sys + from grafana_backup.api_checks import main as api_checks from grafana_backup.dashboardApi import set_user_role def main(args, settings): users_file = args.get('', None) - print("got users_file {0}".format(users_file)) + print('got users_file {0}'.format(users_file)) (status, json_resp, uid_support, paging_support) = api_checks(settings) @@ -28,8 +29,10 @@ def main(args, settings): for user in users: if user['role'] == 'Editor': - (status, content) = set_user_role(user['userId'], 'Editor', grafana_url, http_post_headers, verify_ssl, client_cert, debug) - print("changed user {0} to Editor".format(user['login'])) + (status, content) = set_user_role( + user['userId'], 'Editor', grafana_url, http_post_headers, verify_ssl, client_cert, debug + ) + print('changed user {0} to Editor'.format(user['login'])) if status != 200: - print("changing role of user {0} failed with {1}".format(user['login'], status)) + print('changing role of user {0} failed with {1}'.format(user['login'], status)) diff --git a/grafana_backup/s3_common.py b/grafana_backup/s3_common.py index 8ff5e2a..2a46c4b 100644 --- a/grafana_backup/s3_common.py +++ b/grafana_backup/s3_common.py @@ -1,11 +1,10 @@ import boto3 -from botocore.exceptions import NoCredentialsError, ClientError def get_boto_session(settings) -> boto3.Session: - aws_default_region = settings.get("AWS_DEFAULT_REGION") - aws_access_key_id = settings.get("AWS_ACCESS_KEY_ID") - aws_secret_access_key = settings.get("AWS_SECRET_ACCESS_KEY") + aws_default_region = settings.get('AWS_DEFAULT_REGION') + aws_access_key_id = settings.get('AWS_ACCESS_KEY_ID') + aws_secret_access_key = settings.get('AWS_SECRET_ACCESS_KEY') # If no credentials are provided, boto3 will use the default credentials provider chain. if aws_access_key_id is None or aws_secret_access_key is None: @@ -23,9 +22,9 @@ def get_boto_session(settings) -> boto3.Session: def get_s3_resource(settings): session = get_boto_session(settings) - aws_endpoint_url = settings.get("AWS_ENDPOINT_URL") + aws_endpoint_url = settings.get('AWS_ENDPOINT_URL') s3 = session.resource( - service_name="s3", + service_name='s3', endpoint_url=aws_endpoint_url, ) return s3 @@ -36,7 +35,6 @@ def get_s3_object(settings, s3_file_name): aws_s3_bucket_key = settings.get('AWS_S3_BUCKET_KEY') s3 = get_s3_resource(settings) - s3_object = s3.Object(aws_s3_bucket_name, - '{0}/{1}'.format(aws_s3_bucket_key, s3_file_name)) + s3_object = s3.Object(aws_s3_bucket_name, '{0}/{1}'.format(aws_s3_bucket_key, s3_file_name)) return s3_object diff --git a/grafana_backup/s3_download.py b/grafana_backup/s3_download.py index 79a8e48..4c818ac 100644 --- a/grafana_backup/s3_download.py +++ b/grafana_backup/s3_download.py @@ -1,29 +1,28 @@ -import boto3 -from botocore.exceptions import NoCredentialsError, ClientError from io import BytesIO +from botocore.exceptions import ClientError, NoCredentialsError + from grafana_backup.s3_common import get_s3_object def main(args, settings): - arg_archive_file = args.get("", None) + arg_archive_file = args.get('', None) aws_s3_bucket_name = settings.get('AWS_S3_BUCKET_NAME') s3_object = get_s3_object(settings, s3_file_name=arg_archive_file) try: # .read() left off on purpose, tarfile.open() takes care of that part - s3_data_raw = s3_object.get()["Body"] + s3_data_raw = s3_object.get()['Body'] s3_data = BytesIO(s3_data_raw.read()) - print("Download from S3 was successful") + print('Download from S3 was successful') except ClientError as e: - if e.response["Error"]["Code"] == "NoSuchKey": - print("Error: Key {0} does not exist in bucket {1}".format( - s3_object.key, aws_s3_bucket_name)) + if e.response['Error']['Code'] == 'NoSuchKey': + print('Error: Key {0} does not exist in bucket {1}'.format(s3_object.key, aws_s3_bucket_name)) return False raise e except NoCredentialsError: - print("Credentials not available") + print('Credentials not available') return False return s3_data diff --git a/grafana_backup/s3_upload.py b/grafana_backup/s3_upload.py index daa61da..d9363eb 100644 --- a/grafana_backup/s3_upload.py +++ b/grafana_backup/s3_upload.py @@ -1,4 +1,3 @@ -import boto3 from botocore.exceptions import NoCredentialsError from grafana_backup.s3_common import get_s3_object @@ -15,12 +14,12 @@ def main(args, settings): try: s3_object.put(Body=open(archive_file, 'rb')) - print("Upload to S3 was successful") + print('Upload to S3 was successful') except FileNotFoundError: # noqa: F821 - print("The file was not found") + print('The file was not found') return False except NoCredentialsError: - print("Credentials not available") + print('Credentials not available') return False return True diff --git a/grafana_backup/save.py b/grafana_backup/save.py index 70eb402..a8537fb 100755 --- a/grafana_backup/save.py +++ b/grafana_backup/save.py @@ -1,56 +1,54 @@ +import sys + from grafana_backup.api_checks import main as api_checks +from grafana_backup.archive import main as archive +from grafana_backup.azure_storage_upload import main as azure_storage_upload +from grafana_backup.gcs_upload import main as gcs_upload +from grafana_backup.influx import main as influx +from grafana_backup.s3_upload import main as s3_upload +from grafana_backup.save_alert_channels import main as save_alert_channels from grafana_backup.save_alert_rules import main as save_alert_rules +from grafana_backup.save_annotations import main as save_annotations +from grafana_backup.save_contact_points import main as save_contact_points +from grafana_backup.save_dashboard_versions import main as save_dashboard_versions from grafana_backup.save_dashboards import main as save_dashboards from grafana_backup.save_datasources import main as save_datasources from grafana_backup.save_folders import main as save_folders -from grafana_backup.save_alert_channels import main as save_alert_channels -from grafana_backup.save_snapshots import main as save_snapshots -from grafana_backup.save_dashboard_versions import main as save_dashboard_versions -from grafana_backup.save_annotations import main as save_annotations -from grafana_backup.save_contact_points import main as save_contact_points +from grafana_backup.save_library_elements import main as save_library_elements from grafana_backup.save_notification_policies import main as save_notification_policies -from grafana_backup.archive import main as archive -from grafana_backup.s3_upload import main as s3_upload -from grafana_backup.influx import main as influx from grafana_backup.save_orgs import main as save_orgs -from grafana_backup.save_users import main as save_users -from grafana_backup.save_library_elements import main as save_library_elements -from grafana_backup.save_teams import main as save_teams +from grafana_backup.save_snapshots import main as save_snapshots from grafana_backup.save_team_members import main as save_team_members -from grafana_backup.azure_storage_upload import main as azure_storage_upload -from grafana_backup.gcs_upload import main as gcs_upload -from grafana_backup.commons import print_horizontal_line -import sys +from grafana_backup.save_teams import main as save_teams +from grafana_backup.save_users import main as save_users def main(args, settings): arg_components = args.get('--components', False) arg_no_archive = args.get('--no-archive', False) - backup_functions = {'dashboards': save_dashboards, - 'datasources': save_datasources, - 'folders': save_folders, - 'alert-channels': save_alert_channels, - 'organizations': save_orgs, - 'users': save_users, - 'snapshots': save_snapshots, - 'versions': save_dashboard_versions, # left for backwards compatibility - 'dashboard-versions': save_dashboard_versions, - 'annotations': save_annotations, - 'library-elements': save_library_elements, - 'teams': save_teams, - 'team-members': save_team_members, - 'alert-rules': save_alert_rules, - 'contact-points': save_contact_points, - 'notification-policy': save_notification_policies, - } + backup_functions = { + 'dashboards': save_dashboards, + 'datasources': save_datasources, + 'folders': save_folders, + 'alert-channels': save_alert_channels, + 'organizations': save_orgs, + 'users': save_users, + 'snapshots': save_snapshots, + 'versions': save_dashboard_versions, # left for backwards compatibility + 'dashboard-versions': save_dashboard_versions, + 'annotations': save_annotations, + 'library-elements': save_library_elements, + 'teams': save_teams, + 'team-members': save_team_members, + 'alert-rules': save_alert_rules, + 'contact-points': save_contact_points, + 'notification-policy': save_notification_policies, + } - (status, - json_resp, - dashboard_uid_support, - datasource_uid_support, - paging_support, - contact_point_support) = api_checks(settings) + (status, json_resp, dashboard_uid_support, datasource_uid_support, paging_support, contact_point_support) = ( + api_checks(settings) + ) settings.update({'DASHBOARD_UID_SUPPORT': dashboard_uid_support}) settings.update({'DATASOURCE_UID_SUPPORT': datasource_uid_support}) @@ -59,11 +57,11 @@ def main(args, settings): # Do not continue if API is unavailable or token is not valid if not status == 200: - print("grafana server status is not ok: {0}".format(json_resp)) + print('grafana server status is not ok: {0}'.format(json_resp)) sys.exit(1) if arg_components: - arg_components_list = arg_components.replace("_", "-").split(',') + arg_components_list = arg_components.replace('_', '-').split(',') # Backup only the components that provided via an argument for backup_function in arg_components_list: diff --git a/grafana_backup/save_alert_channels.py b/grafana_backup/save_alert_channels.py index 563c325..85be286 100644 --- a/grafana_backup/save_alert_channels.py +++ b/grafana_backup/save_alert_channels.py @@ -1,6 +1,7 @@ import os + +from grafana_backup.commons import print_horizontal_line, save_json, to_python2_and_3_compatible_string from grafana_backup.dashboardApi import search_alert_channels -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line, save_json def main(args, settings): @@ -28,24 +29,24 @@ def get_all_alert_channels_in_grafana(grafana_url, http_get_headers, verify_ssl, (status, content) = search_alert_channels(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: channels = content - print("There are {0} channels:".format(len(channels))) + print('There are {0} channels:'.format(len(channels))) for channel in channels: - print("name: {0}".format(to_python2_and_3_compatible_string(channel['name']))) + print('name: {0}'.format(to_python2_and_3_compatible_string(channel['name']))) return channels else: - print("query alert channels failed, status: {0}, msg: {1}".format(status, content)) + print('query alert channels failed, status: {0}, msg: {1}'.format(status, content)) return [] def save_alert_channel(channel_name, file_name, alert_channel_setting, folder_path, pretty_print): file_path = save_json(file_name, alert_channel_setting, folder_path, 'alert_channel', pretty_print) - print("alert_channel:{0} is saved to {1}".format(channel_name, file_path)) + print('alert_channel:{0} is saved to {1}'.format(channel_name, file_path)) def get_individual_alert_channel_and_save(channels, folder_path, log_file, pretty_print): file_path = folder_path + '/' + log_file if channels: - with open(u"{0}".format(file_path), 'w') as f: + with open('{0}'.format(file_path), 'w') as f: for channel in channels: if 'uid' in channel: channel_identifier = channel['uid'] @@ -57,7 +58,11 @@ def get_individual_alert_channel_and_save(channels, folder_path, log_file, prett to_python2_and_3_compatible_string(str(channel_identifier)), channel, folder_path, - pretty_print + pretty_print, + ) + f.write( + '{0}\t{1}\n'.format( + to_python2_and_3_compatible_string(str(channel_identifier)), + to_python2_and_3_compatible_string(channel['name']), + ) ) - f.write('{0}\t{1}\n'.format(to_python2_and_3_compatible_string(str(channel_identifier)), - to_python2_and_3_compatible_string(channel['name']))) diff --git a/grafana_backup/save_alert_rules.py b/grafana_backup/save_alert_rules.py index 0e705fc..3e87837 100644 --- a/grafana_backup/save_alert_rules.py +++ b/grafana_backup/save_alert_rules.py @@ -1,8 +1,10 @@ import os -from grafana_backup.dashboardApi import search_alert_rules, get_alert_rule, get_grafana_version -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line, save_json + from packaging import version +from grafana_backup.commons import print_horizontal_line, save_json, to_python2_and_3_compatible_string +from grafana_backup.dashboardApi import get_grafana_version, search_alert_rules + def main(args, settings): backup_dir = settings.get('BACKUP_DIR') @@ -20,55 +22,51 @@ def main(args, settings): grafana_version = version.parse(grafana_version_string) try: - grafana_version = get_grafana_version( - grafana_url, verify_ssl, http_get_headers) + 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: - if not os.path.exists(folder_path): os.makedirs(folder_path) - save_alert_rules(folder_path, log_file, grafana_url, - http_get_headers, verify_ssl, client_cert, debug, pretty_print) + save_alert_rules( + folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print + ) else: - print("Unable to save alert rules, requires Grafana version {0} or above. Current version is {1}".format( - minimum_version, grafana_version)) + print( + 'Unable to save alert rules, requires Grafana version {0} or above. Current version is {1}'.format( + minimum_version, grafana_version + ) + ) def get_all_alert_rules_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, debug): - (status, content) = search_alert_rules(grafana_url, - http_get_headers, - verify_ssl, client_cert, - debug) + (status, content) = search_alert_rules(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: alert_rules = content - print("There are {0} alert rules:".format(len(alert_rules))) + print('There are {0} alert rules:'.format(len(alert_rules))) for alert_rule in alert_rules: - print('name: {0}'.format( - to_python2_and_3_compatible_string(alert_rule['title']))) + print('name: {0}'.format(to_python2_and_3_compatible_string(alert_rule['title']))) return alert_rules else: - raise Exception( - "Failed to get alert rules, status: {0}, msg: {1}".format(status, content)) + raise Exception('Failed to get alert rules, status: {0}, msg: {1}'.format(status, content)) -def save_alert_rules(folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print): - alert_rules = get_all_alert_rules_in_grafana( - grafana_url, http_get_headers, verify_ssl, client_cert, debug) +def save_alert_rules( + folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print +): + alert_rules = get_all_alert_rules_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, debug) for alert_rule in alert_rules: print_horizontal_line() print(alert_rule) - file_path = save_json(alert_rule['uid'], - alert_rule, - folder_path, - 'alert_rule', - pretty_print) - print("alert_rule: {0} -> saved to: {1}" - .format(to_python2_and_3_compatible_string(alert_rule['title']), - file_path)) + file_path = save_json(alert_rule['uid'], alert_rule, folder_path, 'alert_rule', pretty_print) + print( + 'alert_rule: {0} -> saved to: {1}'.format( + to_python2_and_3_compatible_string(alert_rule['title']), file_path + ) + ) print_horizontal_line() diff --git a/grafana_backup/save_annotations.py b/grafana_backup/save_annotations.py index 409daf7..0de9fb0 100644 --- a/grafana_backup/save_annotations.py +++ b/grafana_backup/save_annotations.py @@ -1,7 +1,8 @@ import os import time -from grafana_backup.dashboardApi import search_annotations + from grafana_backup.commons import print_horizontal_line, save_json +from grafana_backup.dashboardApi import search_annotations def main(args, settings): @@ -20,34 +21,43 @@ def main(args, settings): if not os.path.exists(folder_path): os.makedirs(folder_path) - get_all_annotations_and_save(folder_path, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print) + get_all_annotations_and_save( + folder_path, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print + ) print_horizontal_line() def save_annotation(file_name, annotation_setting, folder_path, pretty_print): file_path = save_json(file_name, annotation_setting, folder_path, 'annotation', pretty_print) - print("annotation: {0} is saved to {1}".format(file_name, file_path)) + print('annotation: {0} is saved to {1}'.format(file_name, file_path)) -def get_all_annotations_and_save(folder_path, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print): +def get_all_annotations_and_save( + folder_path, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print +): now = int(round(time.time() * 1000)) one_month_in_ms = 31 * 24 * 60 * 60 * 1000 ts_to = now ts_from = now - one_month_in_ms - thirteen_months_retention = (now - (13 * one_month_in_ms)) + thirteen_months_retention = now - (13 * one_month_in_ms) while ts_from > thirteen_months_retention: - status_code_and_content = search_annotations(grafana_url, ts_from, ts_to, http_get_headers, verify_ssl, client_cert, debug) + status_code_and_content = search_annotations( + grafana_url, ts_from, ts_to, http_get_headers, verify_ssl, client_cert, debug + ) if status_code_and_content[0] == 200: annotations_batch = status_code_and_content[1] - print("There are {0} annotations:".format(len(annotations_batch))) + print('There are {0} annotations:'.format(len(annotations_batch))) for annotation in annotations_batch: print(annotation) save_annotation(str(annotation['id']), annotation, folder_path, pretty_print) else: - print("query annotation failed, status: {0}, msg: {1}".format(status_code_and_content[0], - status_code_and_content[1])) + print( + 'query annotation failed, status: {0}, msg: {1}'.format( + status_code_and_content[0], status_code_and_content[1] + ) + ) ts_to = ts_from ts_from = ts_from - one_month_in_ms diff --git a/grafana_backup/save_contact_points.py b/grafana_backup/save_contact_points.py index 8a95545..4991a34 100644 --- a/grafana_backup/save_contact_points.py +++ b/grafana_backup/save_contact_points.py @@ -1,8 +1,10 @@ import os -from grafana_backup.dashboardApi import search_contact_points, get_grafana_version -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line, save_json + from packaging import version +from grafana_backup.commons import print_horizontal_line, save_json, to_python2_and_3_compatible_string +from grafana_backup.dashboardApi import get_grafana_version, search_contact_points + def main(args, settings): backup_dir = settings.get('BACKUP_DIR') @@ -14,7 +16,6 @@ def main(args, settings): debug = settings.get('DEBUG') pretty_print = settings.get('PRETTY_PRINT') folder_path = '{0}/contact_points/{1}'.format(backup_dir, timestamp) - log_file = 'contact_points_{0}.txt'.format(timestamp) grafana_version_string = settings.get('GRAFANA_VERSION') if grafana_version_string: @@ -24,7 +25,7 @@ def main(args, settings): 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.0.0') if minimum_version <= grafana_version: @@ -32,36 +33,40 @@ def main(args, settings): os.makedirs(folder_path) contact_points = get_all_contact_points_in_grafana( - grafana_url, http_get_headers, verify_ssl, client_cert, debug) - save_contact_points('contact_points', contact_points, - folder_path, pretty_print) + grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) + save_contact_points('contact_points', contact_points, folder_path, pretty_print) else: - print("Unable to save contact points, requires Grafana version {0} or above. Current version is {1}".format( - minimum_version, grafana_version)) + print( + 'Unable to save contact points, requires Grafana version {0} or above. Current version is {1}'.format( + minimum_version, grafana_version + ) + ) if not os.path.exists(folder_path): os.makedirs(folder_path) def get_all_contact_points_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, debug): - (status, content) = search_contact_points( - grafana_url, http_get_headers, verify_ssl, client_cert, debug) + (status, content) = search_contact_points(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: contact_points = content - print("There are {0} contact points: ".format(len(contact_points))) + print('There are {0} contact points: '.format(len(contact_points))) for contact_point in contact_points: - print("name: {0}, type: {1}".format(to_python2_and_3_compatible_string( - contact_point['name']), to_python2_and_3_compatible_string(contact_point['type']))) + print( + 'name: {0}, type: {1}'.format( + to_python2_and_3_compatible_string(contact_point['name']), + to_python2_and_3_compatible_string(contact_point['type']), + ) + ) return contact_points else: - print("query contact points failed, status: {0}, msg: {1}".format( - status, content)) + print('query contact points failed, status: {0}, msg: {1}'.format(status, content)) return [] def save_contact_points(file_name, contact_points, folder_path, pretty_print): - file_path = save_json(file_name, contact_points, - folder_path, 'contact_point', pretty_print) + file_path = save_json(file_name, contact_points, folder_path, 'contact_point', pretty_print) print_horizontal_line() - print("contact points are saved to {0}".format(file_path)) + print('contact points are saved to {0}'.format(file_path)) print_horizontal_line() diff --git a/grafana_backup/save_dashboard_versions.py b/grafana_backup/save_dashboard_versions.py index fb76ee3..f06a598 100644 --- a/grafana_backup/save_dashboard_versions.py +++ b/grafana_backup/save_dashboard_versions.py @@ -1,7 +1,8 @@ import os + +from grafana_backup.commons import print_horizontal_line, save_json, to_python2_and_3_compatible_string from grafana_backup.dashboardApi import get_dashboard_versions, get_version from grafana_backup.save_dashboards import get_all_dashboards_in_grafana -from grafana_backup.commons import print_horizontal_line, save_json, to_python2_and_3_compatible_string def main(args, settings): @@ -21,43 +22,97 @@ def main(args, settings): if not os.path.exists(folder_path): os.makedirs(folder_path) - save_dashboard_versions(folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support) + save_dashboard_versions( + folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support + ) -def save_dashboard_versions(folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support): +def save_dashboard_versions( + folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support +): limit = 5000 current_page = 1 while True: - dashboards = get_all_dashboards_in_grafana(current_page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug) + dashboards = get_all_dashboards_in_grafana( + current_page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) print_horizontal_line() if len(dashboards) == 0: break else: current_page += 1 - get_versions_and_save(dashboards, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support) + get_versions_and_save( + dashboards, + folder_path, + log_file, + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + pretty_print, + uid_support, + ) print_horizontal_line() -def get_versions_and_save(dashboards, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support): +def get_versions_and_save( + dashboards, + folder_path, + log_file, + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + pretty_print, + uid_support, +): if dashboards: for board in dashboards: board_folder_path = os.path.join(folder_path, board['uid']) if not os.path.exists(board_folder_path): os.makedirs(board_folder_path) - (status, content) = get_dashboard_versions(board['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) + (status, content) = get_dashboard_versions( + board['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) if status == 200: - print("found {0} versions for dashboard {1}".format(len(content), to_python2_and_3_compatible_string(board['title']))) - get_individual_versions(content['versions'], board_folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print) + print( + 'found {0} versions for dashboard {1}'.format( + len(content), to_python2_and_3_compatible_string(board['title']) + ) + ) + get_individual_versions( + content['versions'], + board_folder_path, + log_file, + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + pretty_print, + ) -def get_individual_versions(versions, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print): +def get_individual_versions( + versions, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print +): file_path = folder_path + '/' + log_file if versions: - with open(u"{0}".format(file_path), 'w') as f: + with open('{0}'.format(file_path), 'w') as f: for version in versions: - (status, content) = get_version(version['dashboardId'], version['version'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) + (status, content) = get_version( + version['dashboardId'], + version['version'], + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + ) if status == 200: save_version(str(version['version']), content, folder_path, pretty_print) f.write('{0}\n'.format(version['version'])) @@ -65,4 +120,4 @@ def get_individual_versions(versions, folder_path, log_file, grafana_url, http_g def save_version(file_name, version, folder_path, pretty_print): file_path = save_json(file_name, version, folder_path, 'version', pretty_print) - print("version: {0} -> saved to: {1}".format(file_name, file_path)) + print('version: {0} -> saved to: {1}'.format(file_name, file_path)) diff --git a/grafana_backup/save_dashboards.py b/grafana_backup/save_dashboards.py index 03bb34a..95e75c4 100644 --- a/grafana_backup/save_dashboards.py +++ b/grafana_backup/save_dashboards.py @@ -1,6 +1,7 @@ import os -from grafana_backup.dashboardApi import search_dashboard, get_dashboard -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line, save_json + +from grafana_backup.commons import print_horizontal_line, save_json, to_python2_and_3_compatible_string +from grafana_backup.dashboardApi import get_dashboard, search_dashboard def main(args, settings): @@ -24,45 +25,77 @@ def main(args, settings): os.makedirs(folder_path) if paging_support: - save_dashboards_above_Ver6_2(folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support, uid_dashboard_slug_suffix) + save_dashboards_above_Ver6_2( + folder_path, + log_file, + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + pretty_print, + uid_support, + uid_dashboard_slug_suffix, + ) else: - save_dashboards(folder_path, log_file, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support, uid_dashboard_slug_suffix) + save_dashboards( + folder_path, + log_file, + limit, + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + pretty_print, + uid_support, + uid_dashboard_slug_suffix, + ) def get_all_dashboards_in_grafana(page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - (status, content) = search_dashboard(page, - limit, - grafana_url, - http_get_headers, - verify_ssl, client_cert, - debug) + (status, content) = search_dashboard(page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: dashboards = content - print("There are {0} dashboards:".format(len(dashboards))) + print('There are {0} dashboards:'.format(len(dashboards))) for board in dashboards: print('name: {0}'.format(to_python2_and_3_compatible_string(board['title']))) return dashboards else: - print("get dashboards failed, status: {0}, msg: {1}".format(status, content)) + print('get dashboards failed, status: {0}, msg: {1}'.format(status, content)) return [] def save_dashboard_setting(dashboard_name, file_name, dashboard_settings, folder_path, pretty_print): file_path = save_json(file_name, dashboard_settings, folder_path, 'dashboard', pretty_print) - print("dashboard: {0} -> saved to: {1}".format(dashboard_name, file_path)) - - -def get_individual_dashboard_setting_and_save(dashboards, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support, slug_suffix): + print('dashboard: {0} -> saved to: {1}'.format(dashboard_name, file_path)) + + +def get_individual_dashboard_setting_and_save( + dashboards, + folder_path, + log_file, + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + pretty_print, + uid_support, + slug_suffix, +): file_path = folder_path + '/' + log_file if dashboards: - with open(u"{0}".format(file_path), 'w') as f: + with open('{0}'.format(file_path), 'w') as f: for board in dashboards: if uid_support: - board_uri = "uid/{0}".format(board['uid']) + board_uri = 'uid/{0}'.format(board['uid']) else: board_uri = board['uri'] - (status, content) = get_dashboard(board_uri, grafana_url, http_get_headers, verify_ssl, client_cert, debug) + (status, content) = get_dashboard( + board_uri, grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) if status == 200: file_name = build_filename(board_uri, content, uid_support, slug_suffix) save_dashboard_setting( @@ -70,7 +103,7 @@ def get_individual_dashboard_setting_and_save(dashboards, folder_path, log_file, file_name, content, folder_path, - pretty_print + pretty_print, ) f.write('{0}\t{1}\n'.format(board_uri, to_python2_and_3_compatible_string(board['title']))) @@ -81,29 +114,80 @@ def build_filename(board_uri, content, uid_support, slug_suffix): return file_name if not slug_suffix: return file_name - slug = content.get("meta", {}).get("slug") - suffix = "" if slug is None else "-" + slug - file_name = "{0}{1}".format(board_uri, suffix) + slug = content.get('meta', {}).get('slug') + suffix = '' if slug is None else '-' + slug + file_name = '{0}{1}'.format(board_uri, suffix) return file_name -def save_dashboards_above_Ver6_2(folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support, slug_suffix): +def save_dashboards_above_Ver6_2( + folder_path, + log_file, + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + pretty_print, + uid_support, + slug_suffix, +): limit = 5000 # limit is 5000 above V6.2+ current_page = 1 while True: - dashboards = get_all_dashboards_in_grafana(current_page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug) + dashboards = get_all_dashboards_in_grafana( + current_page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) print_horizontal_line() if len(dashboards) == 0: break else: current_page += 1 - get_individual_dashboard_setting_and_save(dashboards, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support, slug_suffix) + get_individual_dashboard_setting_and_save( + dashboards, + folder_path, + log_file, + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + pretty_print, + uid_support, + slug_suffix, + ) print_horizontal_line() -def save_dashboards(folder_path, log_file, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support, slug_suffix): +def save_dashboards( + folder_path, + log_file, + limit, + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + pretty_print, + uid_support, + slug_suffix, +): current_page = 1 - dashboards = get_all_dashboards_in_grafana(current_page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug) + dashboards = get_all_dashboards_in_grafana( + current_page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) print_horizontal_line() - get_individual_dashboard_setting_and_save(dashboards, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support, slug_suffix) + get_individual_dashboard_setting_and_save( + dashboards, + folder_path, + log_file, + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + pretty_print, + uid_support, + slug_suffix, + ) print_horizontal_line() diff --git a/grafana_backup/save_datasources.py b/grafana_backup/save_datasources.py index 3990e77..2ad6851 100644 --- a/grafana_backup/save_datasources.py +++ b/grafana_backup/save_datasources.py @@ -1,6 +1,7 @@ import os -from grafana_backup.dashboardApi import search_datasource + from grafana_backup.commons import print_horizontal_line, save_json +from grafana_backup.dashboardApi import search_datasource def main(args, settings): @@ -19,20 +20,24 @@ def main(args, settings): if not os.path.exists(folder_path): os.makedirs(folder_path) - get_all_datasources_and_save(folder_path, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support) + get_all_datasources_and_save( + folder_path, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support + ) print_horizontal_line() def save_datasource(file_name, datasource_setting, folder_path, pretty_print): file_path = save_json(file_name, datasource_setting, folder_path, 'datasource', pretty_print) - print("datasource:{0} is saved to {1}".format(file_name, file_path)) + print('datasource:{0} is saved to {1}'.format(file_name, file_path)) -def get_all_datasources_and_save(folder_path, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support): +def get_all_datasources_and_save( + folder_path, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support +): status_code_and_content = search_datasource(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status_code_and_content[0] == 200: datasources = status_code_and_content[1] - print("There are {0} datasources:".format(len(datasources))) + print('There are {0} datasources:'.format(len(datasources))) for datasource in datasources: print(datasource) if uid_support: @@ -41,5 +46,8 @@ def get_all_datasources_and_save(folder_path, grafana_url, http_get_headers, ver datasource_name = datasource['name'] save_datasource(datasource_name, datasource, folder_path, pretty_print) else: - print("query datasource failed, status: {0}, msg: {1}".format(status_code_and_content[0], - status_code_and_content[1])) + print( + 'query datasource failed, status: {0}, msg: {1}'.format( + status_code_and_content[0], status_code_and_content[1] + ) + ) diff --git a/grafana_backup/save_folders.py b/grafana_backup/save_folders.py index 65c1130..0ba427e 100644 --- a/grafana_backup/save_folders.py +++ b/grafana_backup/save_folders.py @@ -1,7 +1,7 @@ import os -import json -from grafana_backup.dashboardApi import search_folders, get_folder, get_folder_permissions -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line, save_json + +from grafana_backup.commons import print_horizontal_line, save_json, to_python2_and_3_compatible_string +from grafana_backup.dashboardApi import get_folder, get_folder_permissions, search_folders def main(args, settings): @@ -23,7 +23,18 @@ def main(args, settings): folders = get_all_folders_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, debug) print_horizontal_line() - get_individual_folder_setting_and_save(folders, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support) + get_individual_folder_setting_and_save( + folders, + folder_path, + log_file, + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + pretty_print, + uid_support, + ) print_horizontal_line() @@ -33,34 +44,50 @@ def get_all_folders_in_grafana(grafana_url, http_get_headers, verify_ssl, client content = status_and_content_of_all_folders[1] if status == 200: folders = content - print("There are {0} folders:".format(len(content))) + print('There are {0} folders:'.format(len(content))) for folder in folders: - print("name: {0}".format(to_python2_and_3_compatible_string(folder['title']))) + print('name: {0}'.format(to_python2_and_3_compatible_string(folder['title']))) return folders else: - print("get folders failed, status: {0}, msg: {1}".format(status, content)) + print('get folders failed, status: {0}, msg: {1}'.format(status, content)) return [] def save_folder_setting(folder_name, file_name, folder_settings, folder_permissions, folder_path, pretty_print): file_path = save_json(file_name, folder_settings, folder_path, 'folder', pretty_print) - print("folder:{0} are saved to {1}".format(folder_name, file_path)) - # NOTICE: The 'folder_permission' file extension had the 's' removed to work with the magical dict logic in restore.py... - file_path = save_json(file_name, folder_permissions, folder_path, 'folder_permission', pretty_print) - print("folder permissions:{0} are saved to {1}".format(folder_name, file_path)) + print('folder:{0} are saved to {1}'.format(folder_name, file_path)) + # NOTICE: The 'folder_permission' file extension had the 's' removed to work + # with the magical dict logic in restore.py... + file_path = save_json(file_name, folder_permissions, folder_path, 'folder_permission', pretty_print) + print('folder permissions:{0} are saved to {1}'.format(folder_name, file_path)) -def get_individual_folder_setting_and_save(folders, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print, uid_support): +def get_individual_folder_setting_and_save( + folders, + folder_path, + log_file, + grafana_url, + http_get_headers, + verify_ssl, + client_cert, + debug, + pretty_print, + uid_support, +): file_path = folder_path + '/' + log_file - with open(u"{0}".format(file_path), 'w+') as f: + with open('{0}'.format(file_path), 'w+') as f: for folder in folders: if uid_support: - folder_uri = "uid/{0}".format(folder['uid']) + folder_uri = 'uid/{0}'.format(folder['uid']) else: folder_uri = folder['uri'] - (status_folder_settings, content_folder_settings) = get_folder(folder['uid'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) - (status_folder_permissions, content_folder_permissions) = get_folder_permissions(folder['uid'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) + (status_folder_settings, content_folder_settings) = get_folder( + folder['uid'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) + (status_folder_permissions, content_folder_permissions) = get_folder_permissions( + folder['uid'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) if status_folder_settings == 200 and status_folder_permissions == 200: save_folder_setting( @@ -69,6 +96,6 @@ def get_individual_folder_setting_and_save(folders, folder_path, log_file, grafa content_folder_settings, content_folder_permissions, folder_path, - pretty_print + pretty_print, ) f.write('{0}\t{1}\n'.format(folder_uri, to_python2_and_3_compatible_string(folder['title']))) diff --git a/grafana_backup/save_library_elements.py b/grafana_backup/save_library_elements.py index 882196d..b3a6e22 100644 --- a/grafana_backup/save_library_elements.py +++ b/grafana_backup/save_library_elements.py @@ -1,6 +1,7 @@ import os + +from grafana_backup.commons import print_horizontal_line, save_json, to_python2_and_3_compatible_string from grafana_backup.dashboardApi import search_library_elements -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line, save_json def main(args, settings): @@ -19,7 +20,9 @@ def main(args, settings): if not os.path.exists(folder_path): os.makedirs(folder_path) - library_elements = get_all_library_elements_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, debug) + library_elements = get_all_library_elements_in_grafana( + grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) get_individual_library_elements_and_save(library_elements, folder_path, log_file, pretty_print) print_horizontal_line() @@ -28,24 +31,24 @@ def get_all_library_elements_in_grafana(grafana_url, http_get_headers, verify_ss (status, content) = search_library_elements(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: library_elements = content['result']['elements'] - print("There are {0} library element:".format(len(library_elements))) + print('There are {0} library element:'.format(len(library_elements))) for library_element in library_elements: - print("name: {0}".format(to_python2_and_3_compatible_string(library_element['name']))) + print('name: {0}'.format(to_python2_and_3_compatible_string(library_element['name']))) return library_elements else: - print("query library elements failed, status: {0}, msg: {1}".format(status, content)) + print('query library elements failed, status: {0}, msg: {1}'.format(status, content)) return [] def save_library_element(channel_name, file_name, alert_channel_setting, folder_path, pretty_print): file_path = save_json(file_name, alert_channel_setting, folder_path, 'library_element', pretty_print) - print("library_element:{0} is saved to {1}".format(channel_name, file_path)) + print('library_element:{0} is saved to {1}'.format(channel_name, file_path)) def get_individual_library_elements_and_save(library_elements, folder_path, log_file, pretty_print): file_path = folder_path + '/' + log_file if library_elements: - with open(u"{0}".format(file_path), 'w') as f: + with open('{0}'.format(file_path), 'w') as f: for library_element in library_elements: if 'uid' in library_element: library_element_identifier = library_element['uid'] @@ -57,8 +60,11 @@ def get_individual_library_elements_and_save(library_elements, folder_path, log_ to_python2_and_3_compatible_string(str(library_element_identifier)), library_element, folder_path, - pretty_print + pretty_print, + ) + f.write( + '{0}\t{1}\n'.format( + to_python2_and_3_compatible_string(str(library_element_identifier)), + to_python2_and_3_compatible_string(library_element['name']), + ) ) - f.write('{0}\t{1}\n'.format(to_python2_and_3_compatible_string(str(library_element_identifier)), - to_python2_and_3_compatible_string(library_element['name']))) - diff --git a/grafana_backup/save_notification_policies.py b/grafana_backup/save_notification_policies.py index dcf7ab8..960d6e5 100644 --- a/grafana_backup/save_notification_policies.py +++ b/grafana_backup/save_notification_policies.py @@ -1,8 +1,10 @@ import os -from grafana_backup.dashboardApi import search_notification_policies, get_grafana_version -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line, save_json + from packaging import version +from grafana_backup.commons import print_horizontal_line, save_json +from grafana_backup.dashboardApi import get_grafana_version, search_notification_policies + def main(args, settings): backup_dir = settings.get('BACKUP_DIR') @@ -14,7 +16,7 @@ def main(args, settings): debug = settings.get('DEBUG') pretty_print = settings.get('PRETTY_PRINT') folder_path = '{0}/notification_policies/{1}'.format(backup_dir, timestamp) - log_file = 'notification_policies_{0}.txt'.format(timestamp) + # log_file = "notification_policies_{0}.txt".format(timestamp) grafana_version_string = settings.get('GRAFANA_VERSION') if grafana_version_string: @@ -24,7 +26,7 @@ def main(args, settings): 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.0.0') if minimum_version <= grafana_version: @@ -32,33 +34,32 @@ def main(args, settings): os.makedirs(folder_path) notification_policies = get_all_notification_policies_in_grafana( - grafana_url, http_get_headers, verify_ssl, client_cert, debug) - save_notification_policies( - 'notificatioin_policies', notification_policies, folder_path, pretty_print) + grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) + save_notification_policies('notificatioin_policies', notification_policies, folder_path, pretty_print) else: - print("Unable to save notification policies, requires Grafana version {0} or above. Current version is {1}".format( - minimum_version, grafana_version)) + print( + 'Unable to save notification policies, requires Grafana version {0} ' + 'or above. Current version is {1}'.format(minimum_version, grafana_version) + ) if not os.path.exists(folder_path): os.makedirs(folder_path) def get_all_notification_policies_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, debug): - (status, content) = search_notification_policies( - grafana_url, http_get_headers, verify_ssl, client_cert, debug) + (status, content) = search_notification_policies(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: notification_policies = content - print("Notification policies found") + print('Notification policies found') return notification_policies else: - print("query notification policies failed, status: {0}, msg: {1}".format( - status, content)) + print('query notification policies failed, status: {0}, msg: {1}'.format(status, content)) return [] def save_notification_policies(file_name, notification_policies, folder_path, pretty_print): - file_path = save_json(file_name, notification_policies, - folder_path, 'notification_policys', pretty_print) + file_path = save_json(file_name, notification_policies, folder_path, 'notification_policys', pretty_print) print_horizontal_line() - print("notification policies are saved to {0}".format(file_path)) + print('notification policies are saved to {0}'.format(file_path)) print_horizontal_line() diff --git a/grafana_backup/save_orgs.py b/grafana_backup/save_orgs.py index b5dcaf2..42308f5 100755 --- a/grafana_backup/save_orgs.py +++ b/grafana_backup/save_orgs.py @@ -1,6 +1,7 @@ import os -from grafana_backup.dashboardApi import search_orgs, get_org -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line, save_json + +from grafana_backup.commons import print_horizontal_line, save_json, to_python2_and_3_compatible_string +from grafana_backup.dashboardApi import get_org, search_orgs def main(args, settings): @@ -20,39 +21,45 @@ def main(args, settings): if not os.path.exists(folder_path): os.makedirs(folder_path) - save_orgs(folder_path, log_file, grafana_url, http_get_headers_basic_auth, verify_ssl, client_cert, debug, pretty_print) + save_orgs( + folder_path, + log_file, + grafana_url, + http_get_headers_basic_auth, + verify_ssl, + client_cert, + debug, + pretty_print, + ) else: print('[ERROR] Backing up organizations needs to set GRAFANA_ADMIN_ACCOUNT and GRAFANA_ADMIN_PASSWORD first.') print_horizontal_line() def get_all_orgs_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, debug): - (status, content) = search_orgs(grafana_url, - http_get_headers, - verify_ssl, - client_cert, - debug) + (status, content) = search_orgs(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: orgs = content - print("There are {0} orgs:".format(len(orgs))) + print('There are {0} orgs:'.format(len(orgs))) for org in orgs: print('name: {0}'.format(to_python2_and_3_compatible_string(org['name']))) return orgs else: - print("get orgs failed, status: {0}, msg: {1}".format(status, content)) + print('get orgs failed, status: {0}, msg: {1}'.format(status, content)) return [] def save_org_info(org_name, file_name, org_settings, folder_path, pretty_print): file_path = save_json(file_name, org_settings, folder_path, 'organization', pretty_print) - print("org: {0} -> saved to: {1}".format(org_name, file_path)) + print('org: {0} -> saved to: {1}'.format(org_name, file_path)) -def get_individual_org_info_and_save(orgs, folder_path, log_file, grafana_url, http_get_headers, - verify_ssl, client_cert, debug, pretty_print): +def get_individual_org_info_and_save( + orgs, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print +): file_path = folder_path + '/' + log_file if orgs: - with open(u"{0}".format(file_path), 'w') as log_file: + with open('{0}'.format(file_path), 'w') as log_file: for org in orgs: (status, content) = get_org(org['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: @@ -61,15 +68,15 @@ def get_individual_org_info_and_save(orgs, folder_path, log_file, grafana_url, h str(org['id']), content, folder_path, - pretty_print + pretty_print, ) log_file.write('{0}\t{1}\n'.format(org['id'], to_python2_and_3_compatible_string(org['name']))) def save_orgs(folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print): - orgs = get_all_orgs_in_grafana(grafana_url, http_get_headers, verify_ssl, - client_cert, debug) + orgs = get_all_orgs_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, debug) print_horizontal_line() - get_individual_org_info_and_save(orgs, folder_path, log_file, grafana_url, http_get_headers, - verify_ssl, client_cert, debug, pretty_print) + get_individual_org_info_and_save( + orgs, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print + ) print_horizontal_line() diff --git a/grafana_backup/save_snapshots.py b/grafana_backup/save_snapshots.py index 254f7e1..5ad804f 100644 --- a/grafana_backup/save_snapshots.py +++ b/grafana_backup/save_snapshots.py @@ -1,8 +1,9 @@ import os import random import string -from grafana_backup.dashboardApi import search_snapshot, get_snapshot + from grafana_backup.commons import print_horizontal_line, save_json +from grafana_backup.dashboardApi import get_snapshot, search_snapshot def main(args, settings): @@ -27,27 +28,36 @@ def main(args, settings): def save_snapshot(file_name, snapshot_setting, folder_path, pretty_print): file_name = file_name.replace('/', '_') - random_suffix = "".join(random.choice(string.ascii_letters) for _ in range(6)) - file_path = save_json(file_name + "_" + random_suffix, snapshot_setting, folder_path, 'snapshot', pretty_print) - print("snapshot:{0} is saved to {1}".format(file_name, file_path)) + random_suffix = ''.join(random.choice(string.ascii_letters) for _ in range(6)) + file_path = save_json(file_name + '_' + random_suffix, snapshot_setting, folder_path, 'snapshot', pretty_print) + print('snapshot:{0} is saved to {1}'.format(file_name, file_path)) -def get_single_snapshot_and_save(snapshot, grafana_url, http_get_headers, verify_ssl, client_cert, debug, folder_path, pretty_print): +def get_single_snapshot_and_save( + snapshot, grafana_url, http_get_headers, verify_ssl, client_cert, debug, folder_path, pretty_print +): (status, content) = get_snapshot(snapshot['key'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: save_snapshot(snapshot['name'], content, folder_path, pretty_print) else: - print("getting snapshot {0} failed with {1}".format(snapshot['name'], status)) + print('getting snapshot {0} failed with {1}'.format(snapshot['name'], status)) -def get_all_snapshots_and_save(folder_path, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print): +def get_all_snapshots_and_save( + folder_path, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print +): status_code_and_content = search_snapshot(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status_code_and_content[0] == 200: snapshots = status_code_and_content[1] - print("There are {0} snapshots:".format(len(snapshots))) + print('There are {0} snapshots:'.format(len(snapshots))) for snapshot in snapshots: print(snapshot) - get_single_snapshot_and_save(snapshot, grafana_url, http_get_headers, verify_ssl, client_cert, debug, folder_path, pretty_print) + get_single_snapshot_and_save( + snapshot, grafana_url, http_get_headers, verify_ssl, client_cert, debug, folder_path, pretty_print + ) else: - print("query snapshot failed, status: {0}, msg: {1}".format(status_code_and_content[0], - status_code_and_content[1])) + print( + 'query snapshot failed, status: {0}, msg: {1}'.format( + status_code_and_content[0], status_code_and_content[1] + ) + ) diff --git a/grafana_backup/save_team_members.py b/grafana_backup/save_team_members.py index d74a25f..81a1865 100644 --- a/grafana_backup/save_team_members.py +++ b/grafana_backup/save_team_members.py @@ -1,6 +1,7 @@ import os -from grafana_backup.dashboardApi import search_teams, search_team_members -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line, save_json + +from grafana_backup.commons import print_horizontal_line, save_json, to_python2_and_3_compatible_string +from grafana_backup.dashboardApi import search_team_members, search_teams def main(args, settings): @@ -20,7 +21,9 @@ def main(args, settings): os.makedirs(folderpath) teams = get_all_teams_in_grafana(grafana_url, http_get_headers, verify_ssl, client_cert, debug) - get_individual_team_members_and_save(teams, folderpath, log_file, pretty_print, grafana_url, http_get_headers, verify_ssl, client_cert, debug) + get_individual_team_members_and_save( + teams, folderpath, log_file, pretty_print, grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) print_horizontal_line() @@ -28,12 +31,12 @@ def get_all_teams_in_grafana(grafana_url, http_get_headers, verify_ssl, client_c (status, content) = search_teams(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: teams = content['teams'] - print("There are {0} teams:".format(len(teams))) + print('There are {0} teams:'.format(len(teams))) for team in teams: - print("name: {0}".format(to_python2_and_3_compatible_string(team['name']))) + print('name: {0}'.format(to_python2_and_3_compatible_string(team['name']))) return teams else: - print("query teams failed, status: {0}, msg: {1}".format(status, content)) + print('query teams failed, status: {0}, msg: {1}'.format(status, content)) return [] @@ -41,35 +44,42 @@ def get_team_members_in_grafana(team_id, grafana_url, http_get_headers, verify_s (status, content) = search_team_members(team_id, grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: team_members = content - print("There are {0} team members in team {1}:".format(len(team_members), team_id)) + print('There are {0} team members in team {1}:'.format(len(team_members), team_id)) for team_member in team_members: - print("name: {0}".format(to_python2_and_3_compatible_string(team_member['name']))) + print('name: {0}'.format(to_python2_and_3_compatible_string(team_member['name']))) return team_members else: - print("query team members failed, status: {0}, msg: {1}".format(status, content)) + print('query team members failed, status: {0}, msg: {1}'.format(status, content)) return [] def save_team_member(team_member, file_name, alert_channel_setting, folder_path, pretty_print): file_path = save_json(file_name, alert_channel_setting, folder_path, 'team_member', pretty_print) - print("team:{0} is saved to {1}".format(team_member, file_path)) + print('team:{0} is saved to {1}'.format(team_member, file_path)) -def get_individual_team_members_and_save(teams, folder_path, log_file, pretty_print, grafana_url, http_get_headers, verify_ssl, client_cert, debug): +def get_individual_team_members_and_save( + teams, folder_path, log_file, pretty_print, grafana_url, http_get_headers, verify_ssl, client_cert, debug +): file_path = folder_path + '/' + log_file if teams: - with open(u"{0}".format(file_path), 'w') as f: + with open('{0}'.format(file_path), 'w') as f: for team in teams: - for team_member in get_team_members_in_grafana(team['id'], grafana_url, http_get_headers, verify_ssl, - client_cert, debug): - team_member_identifier = "{0}_{1}".format(team_member['userId'], team_member['teamId']) + for team_member in get_team_members_in_grafana( + team['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ): + team_member_identifier = '{0}_{1}'.format(team_member['userId'], team_member['teamId']) save_team_member( to_python2_and_3_compatible_string(team['name']), to_python2_and_3_compatible_string(str(team_member_identifier)), team_member, folder_path, - pretty_print + pretty_print, + ) + f.write( + '{0}\t{1}\n'.format( + to_python2_and_3_compatible_string(str(team_member_identifier)), + to_python2_and_3_compatible_string(team['name']), + ) ) - f.write('{0}\t{1}\n'.format(to_python2_and_3_compatible_string(str(team_member_identifier)), - to_python2_and_3_compatible_string(team['name']))) diff --git a/grafana_backup/save_teams.py b/grafana_backup/save_teams.py index da40577..547a62c 100644 --- a/grafana_backup/save_teams.py +++ b/grafana_backup/save_teams.py @@ -1,6 +1,7 @@ import os + +from grafana_backup.commons import print_horizontal_line, save_json, to_python2_and_3_compatible_string from grafana_backup.dashboardApi import search_teams -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line, save_json def main(args, settings): @@ -28,24 +29,24 @@ def get_all_teams_in_grafana(grafana_url, http_get_headers, verify_ssl, client_c (status, content) = search_teams(grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: teams = content['teams'] - print("There are {0} teams:".format(len(teams))) + print('There are {0} teams:'.format(len(teams))) for team in teams: - print("name: {0}".format(to_python2_and_3_compatible_string(team['name']))) + print('name: {0}'.format(to_python2_and_3_compatible_string(team['name']))) return teams else: - print("query teams failed, status: {0}, msg: {1}".format(status, content)) + print('query teams failed, status: {0}, msg: {1}'.format(status, content)) return [] def save_team(channel_name, file_name, alert_channel_setting, folder_path, pretty_print): file_path = save_json(file_name, alert_channel_setting, folder_path, 'team', pretty_print) - print("team:{0} is saved to {1}".format(channel_name, file_path)) + print('team:{0} is saved to {1}'.format(channel_name, file_path)) def get_individual_teams_and_save(teams, folder_path, log_file, pretty_print): file_path = folder_path + '/' + log_file if teams: - with open(u"{0}".format(file_path), 'w') as f: + with open('{0}'.format(file_path), 'w') as f: for team in teams: if 'uid' in team: team_identifier = team['uid'] @@ -57,8 +58,11 @@ def get_individual_teams_and_save(teams, folder_path, log_file, pretty_print): to_python2_and_3_compatible_string(str(team_identifier)), team, folder_path, - pretty_print + pretty_print, + ) + f.write( + '{0}\t{1}\n'.format( + to_python2_and_3_compatible_string(str(team_identifier)), + to_python2_and_3_compatible_string(team['name']), + ) ) - f.write('{0}\t{1}\n'.format(to_python2_and_3_compatible_string(str(team_identifier)), - to_python2_and_3_compatible_string(team['name']))) - diff --git a/grafana_backup/save_users.py b/grafana_backup/save_users.py index f1fc0bf..cd1219e 100755 --- a/grafana_backup/save_users.py +++ b/grafana_backup/save_users.py @@ -1,6 +1,7 @@ import os -from grafana_backup.dashboardApi import search_users, get_user_org, get_user -from grafana_backup.commons import to_python2_and_3_compatible_string, print_horizontal_line, save_json + +from grafana_backup.commons import print_horizontal_line, save_json, to_python2_and_3_compatible_string +from grafana_backup.dashboardApi import get_user, get_user_org, search_users def main(args, settings): @@ -21,64 +22,70 @@ def main(args, settings): if not os.path.exists(folder_path): os.makedirs(folder_path) - save_users(folder_path, log_file, limit, grafana_url, http_get_headers_basic_auth, verify_ssl, client_cert, debug, pretty_print) + save_users( + folder_path, + log_file, + limit, + grafana_url, + http_get_headers_basic_auth, + verify_ssl, + client_cert, + debug, + pretty_print, + ) else: print('[ERROR] Backing up users needs to set ENV GRAFANA_ADMIN_ACCOUNT and GRAFANA_ADMIN_PASSWORD first. \n') print_horizontal_line() def get_all_users(page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug): - (status, content) = search_users(page, - limit, - grafana_url, - http_get_headers, - verify_ssl, - client_cert, - debug) + (status, content) = search_users(page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: users = content - print("There are {0} users:".format(len(users))) + print('There are {0} users:'.format(len(users))) for user in users: print('name: {0}'.format(to_python2_and_3_compatible_string(user['name']))) return users else: - print("get users failed, status: {0}, msg: {1}".format(status, content)) + print('get users failed, status: {0}, msg: {1}'.format(status, content)) return [] def save_user_info(user_name, file_name, user_data, folder_path, pretty_print): file_path = save_json(file_name, user_data, folder_path, 'user', pretty_print) - print("user: {0} -> saved to: {1}".format(user_name, file_path)) + print('user: {0} -> saved to: {1}'.format(user_name, file_path)) -def get_individual_user_and_save(users, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, - debug, pretty_print): +def get_individual_user_and_save( + users, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print +): file_path = folder_path + '/' + log_file if users: - with open(u"{0}".format(file_path), 'w') as f: + with open('{0}'.format(file_path), 'w') as f: for user in users: (status, content) = get_user(user['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) if status == 200: user.update(content) - (status, content) = get_user_org(user['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug) + (status, content) = get_user_org( + user['id'], grafana_url, http_get_headers, verify_ssl, client_cert, debug + ) if status == 200: user.update({'orgs': content}) save_user_info( - to_python2_and_3_compatible_string(user['name']), - str(user['id']), - user, - folder_path, - pretty_print + to_python2_and_3_compatible_string(user['name']), str(user['id']), user, folder_path, pretty_print ) f.write('{0}\t{1}\n'.format(user['id'], to_python2_and_3_compatible_string(user['name']))) -def save_users(folder_path, log_file, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print): +def save_users( + folder_path, log_file, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print +): current_page = 1 users = get_all_users(current_page, limit, grafana_url, http_get_headers, verify_ssl, client_cert, debug) print_horizontal_line() - get_individual_user_and_save(users, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, - debug, pretty_print) + get_individual_user_and_save( + users, folder_path, log_file, grafana_url, http_get_headers, verify_ssl, client_cert, debug, pretty_print + ) print_horizontal_line() diff --git a/grafana_backup/tools.py b/grafana_backup/tools.py index a6e671b..70e7c1b 100755 --- a/grafana_backup/tools.py +++ b/grafana_backup/tools.py @@ -1,14 +1,15 @@ -from grafana_backup.constants import (PKG_NAME, PKG_VERSION) -from grafana_backup.pause_alerts import main as pause_alerts -from grafana_backup.unpause_alerts import main as unpause_alerts +import sys + +from docopt import docopt + +from grafana_backup.constants import PKG_NAME, PKG_VERSION from grafana_backup.make_users_viewers import main as make_users_viewers +from grafana_backup.pause_alerts import main as pause_alerts from grafana_backup.restore_user_permissions import main as restore_user_permissions -from docopt import docopt -import sys +from grafana_backup.unpause_alerts import main as unpause_alerts def main(precommand_args, settings): - docstring = """ {0} {1} @@ -25,8 +26,7 @@ def main(precommand_args, settings): --config= Override default configuration path """.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)) combined_args = precommand_args.copy() combined_args.update(args) diff --git a/grafana_backup/unpause_alerts.py b/grafana_backup/unpause_alerts.py index ad58dde..4157187 100755 --- a/grafana_backup/unpause_alerts.py +++ b/grafana_backup/unpause_alerts.py @@ -1,12 +1,13 @@ -import sys import json +import sys + from grafana_backup.api_checks import main as api_checks from grafana_backup.dashboardApi import unpause_alert def main(args, settings): alerts_file = args.get('', None) - print("got alerts_file {0}".format(alerts_file)) + print('got alerts_file {0}'.format(alerts_file)) (status, json_resp, dashboard_uid_support, datasource_uid_support, paging_support) = api_checks(settings) @@ -30,7 +31,7 @@ def main(args, settings): if alert['state'] != 'paused': result = unpause_alert(alert['id'], grafana_url, http_post_headers, verify_ssl, client_cert, debug) if result[0] != 200: - print("failed to unpause alert: {0} - {1} with {2}".format(alert['id'], alert['name'], result[0])) - print("unpausing alert: {0} - {1} with previous state: {2}".format(alert['id'], alert['name'], result[0])) + print('failed to unpause alert: {0} - {1} with {2}'.format(alert['id'], alert['name'], result[0])) + print('unpausing alert: {0} - {1} with previous state: {2}'.format(alert['id'], alert['name'], result[0])) else: - print("keeping alert {0} - {1} paused".format(alert['id'], alert['name'])) + print('keeping alert {0} - {1} paused'.format(alert['id'], alert['name'])) diff --git a/grafana_backup/update_folder_permissions.py b/grafana_backup/update_folder_permissions.py index b030c39..1ba2858 100644 --- a/grafana_backup/update_folder_permissions.py +++ b/grafana_backup/update_folder_permissions.py @@ -1,4 +1,5 @@ import json + from grafana_backup.dashboardApi import update_folder_permissions @@ -14,5 +15,11 @@ def main(args, settings, file_path): folder_permissions = json.loads(data) if folder_permissions: - result = update_folder_permissions(folder_permissions, grafana_url, http_post_headers, verify_ssl, client_cert, debug) - print("update folder permissions {0}, status: {1}, msg: {2}\n".format(folder_permissions[0].get('title', ''), result[0], result[1])) + result = update_folder_permissions( + folder_permissions, grafana_url, http_post_headers, verify_ssl, client_cert, debug + ) + print( + 'update folder permissions {0}, status: {1}, msg: {2}\n'.format( + folder_permissions[0].get('title', ''), result[0], result[1] + ) + ) diff --git a/grafana_backup/update_notification_policy.py b/grafana_backup/update_notification_policy.py index f438806..d2488e9 100644 --- a/grafana_backup/update_notification_policy.py +++ b/grafana_backup/update_notification_policy.py @@ -1,7 +1,9 @@ import json -from grafana_backup.dashboardApi import update_notification_policy, get_grafana_version + from packaging import version +from grafana_backup.dashboardApi import get_grafana_version, update_notification_policy + def main(args, settings, file_path): grafana_url = settings.get('GRAFANA_URL') @@ -15,7 +17,7 @@ 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') @@ -24,10 +26,12 @@ def main(args, settings, file_path): data = f.read() notification_policies = json.loads(data) - result = update_notification_policy(json.dumps( - notification_policies), grafana_url, http_post_headers, verify_ssl, client_cert, debug) - print("update notification_policy, status: {0}, msg: {1}".format( - result[0], result[1])) + result = update_notification_policy( + json.dumps(notification_policies), grafana_url, http_post_headers, verify_ssl, client_cert, debug + ) + print('update notification_policy, status: {0}, msg: {1}'.format(result[0], result[1])) else: - print("Unable to update notification policy, requires Grafana version {0} or above. Current version is {1}".format( - minimum_version, grafana_version)) + print( + 'Unable to update notification policy, requires Grafana version {0} ' + 'or above. Current version is {1}'.format(minimum_version, grafana_version) + ) diff --git a/pyproject.toml b/pyproject.toml index c90ab91..bb7f1af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,19 +21,41 @@ ruff = "0.12.0" pytest = "8.0.0" pytest-cov = "6.0.0" +[tool.pytest.ini_options] +addopts = "ansibledoctor --cov=ansibledoctor --cov-report=xml:coverage.xml --cov-report=term --no-cov-on-fail" +filterwarnings = [ + "ignore::FutureWarning", + "ignore::DeprecationWarning", + "ignore:.*pep8.*:FutureWarning", +] + +[tool.coverage.run] +omit = ["**/test/*"] + [tool.ruff] -target-version = "py310" -line-length = 120 +exclude = [ + ".git", + "__pycache__", + "build", + "dist", + "test", + "*.pyc", + "*.egg-info", + ".cache", + ".eggs", + "env*", +] -[tool.ruff.format] -quote-style = "double" -indent-style = "space" +line-length = 120 +indent-width = 4 [tool.ruff.lint] select = ["E", "F", "I"] -[tool.pytest.ini_options] -testpaths = ["tests"] +[tool.ruff.format] +quote-style = "single" +indent-style = "space" +line-ending = "lf" [tool.poetry.scripts] grafana-backup = "grafana_backup.cli:main"