ysde / grafana-backup-tool Goto Github PK
View Code? Open in Web Editor NEWA Python-based application to backup Grafana settings by using the Grafana API
License: MIT License
A Python-based application to backup Grafana settings by using the Grafana API
License: MIT License
Hi!
This is a nice tool and I really appreciate your work. I changed (quick and dirty) the bash script to simply not remove the files and changed the output directory from "OUTPUT" to "backup".
Similarly I removed the timestamp from the dashboards.txt file.
After a run of the script I add, commit, push ... why versioned tar archives and filenames when there's git?
Kind regards,
Patrick
Dear @ysde,
first things first: Thanks for conceiving this excellent utility.
After taking a look, I recognized the module has not been added to PyPI yet. It would be cool to add an appropriate setup.py
and - while being at it - to wrap the functionality of backup_grafana.sh
/restore_grafana.sh
within respective Python console script entrypoints.
With kind regards,
Andreas.
It's /nin/bash, should be /bin/bash.
Hello
thank you very much for awesome grafana-backup-tool
Can you please add a license file (example GPL, MIT,..) to your repo?
thanks
If you want to continue to support python 2.7, you'll want to change this to w:gz
instead of x:gz
. Or just remove Python 2.7 from requirements in the readme. :)
leads to: TypeError: health_check() missing 1 required positional argument: 'debug'
see:
https://github.com/ysde/grafana-backup-tool/blob/master/grafana_backup/dashboardApi.py#L5
def health_check(grafana_url, http_get_headers, verify_ssl, client_cert, debug)
fix: call health_check with expected args
This is due to a limit in grafna that is hard coded https://github.com/grafana/grafana/blob/50a1feb90a5535ff2ec4f6242e47e4e9209d7575/pkg/services/sqlstore/dashboard.go#L153
I am trying to use this perfectly suited backup script for me.
I have the requirements already.
python --version
Python 2.7.12
pip install requests
You are using pip version 6.1.1, however version 19.0.3 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Requirement already satisfied (use --upgrade to upgrade): requests in /usr/lib/python2.7/dist-packages
but still the script is facing with key error. Below is the error:
Traceback (most recent call last):
File "/home/ec2-user/grafana-backup-tool/saveDashboards.py", line 52, in <module>
get_indivisual_dashboard_setting_and_save(dashboards)
File "/home/ec2-user/grafana-backup-tool/saveDashboards.py", line 43, in get_indivisual_dashboard_setting_and_save
board['uid'],
KeyError: 'uid'
Just installed latest version from git, and found that when I use env vars instead of config files, the aws upload section always attempts an upload using the dummy config values in grafanaSettings.json (bucket_name, et. al). It's currently impossible to avoid the aws upload step when using env vars for conf because the conf directory is packaged up into the installation in setup.py. Also there's a default grafana token in there as well which seems not smart either?
I'm thinking maybe there needs to be an example conf in addition to the default conf, to showcase the aws configs? Not everyone (aka me) wants the tool to upload to aws (I'm uploading to backblaze b2).
Now that everything works (tm), may be it is time to tidy out the default output and introduce some kind of debug/verbose flag...
I'd suggest "-d" and print a help message like:
echo "Please re-run with DEBUG enabled for troubleshooting:"
echo "$0 -d $*"
exit -1
upon error.
Hello.
Thank you for your code. It works very well for me so far, except that the folders it creates when running a backup are empty. It does create a tar.gz file which has the folders inside which are not empty (the backup is working and reading my grafana), however the folders "alert_channels", "dashboards", "data_sources" and "folders" in the root OUTPUT folder are empty.
Is this supposed to be the case or should those folders have the files in them?
Thank you very much
Hamish
For those of us who prefer text/json output (for example to use with source control) it would be useful for JSON files be prettified (and perhaps sorted somehow?) when written to disk.
I'm not too familiar with Python but my work around right now is to apply the json.tool (module?) to each file via a bash script, but I presume that means this can be rolled into the backup tool itself.
Hi,
first of all, thank you for your work.
I ran into the following issue. Its working for most of my dashboards, but some encounter the following issue while saveDashboards.py exports it:
query dashboard uri: db/pxc-galera-graphs, status: 200
Traceback (most recent call last):
File "/grafana-backup-tool/saveDashboards.py", line 48, in
get_indivisual_dashboard_setting_and_save(dashboards)
File "grafana-backup-tool/saveDashboards.py", line 41, in get_indivisual_dashboard_setting_and_save
save_dashboard_setting(board['title'], board['uid'], status_code_and_content[1])
File "grafana-backup-tool/saveDashboards.py", line 33, in save_dashboard_setting
f.write(dashboard_settings)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2013' in position 21376: ordinal not in range(128)
I tried with python 2.7 and 3.6, same issue.
thanks a lot!
search dashboard in grafana:
/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py:851: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
[debug] status: 422
[debug] body: {'message': 'Limit is above maximum allowed (5000), use page parameter to access hits beyond limit'}
get dashboards failed, status: 422, msg: {'message': 'Limit is above maximum allowed (5000), use page parameter to access hits beyond limit'}
Hi,
Thank you for your work.
I have a strange problem but I don't know if it's a grafana or a backup-tool problem :
I'am running Grafana on a kubernetes cluster in a "prometheus" namespace. The backup phase works fine.
To test the restore, I create another grafana instance in a "test" namespace. The restore phase seems to work fine, but I need to update the "prometheus" datasource to make it point to the prometheus datasource. So I go in the datasource menu an I have this :
The datasource was added by config and cannot be modified using the UI
I cannot modify anything here and I cannot delete it. Is there something to do from the backup-tool?
Thank you
Hi
I run backup_grafana.sh
which creates a tarball. When you unpack the tarball there are directories like 2019-07-lOT07:33:06
which is not compatible with windows. I upload the contents of tarball to Git repo.
Please replace : with -
During Git checkout of grafana-backup the Windows guys get:
fatal: cannot create directory at 'grafana-backup-tool/dashboards/2019-07-lOT07:33:06':
Invalid argument
thanks
I see alert channels backed up, but no backup for alert rules?
I think that needs to be added here.
--- a/src/save_dashboards.py
+++ b/src/save_dashboards.py
@@ -42,8 +42,8 @@ def get_indivisual_dashboard_setting_and_save(dashboards):
content
)
file_path = folder_path + '/' + log_file
- with open(u"{0}".format(file_path) , 'w+') as f:
- f.write('{}\t{}'.format(board['uid'], to_python2_and_3_compatible_string(board['title'])))
+ with open(u"{0}".format(file_path) , 'a') as f:
+ f.write('{}\t{}\n'.format(board['uid'], to_python2_and_3_compatible_string(board['title'])))
def save_dashboards_above_Ver6_2():
limit = 5000 # limit is 5000 above V6.2+
Thanks for such a fantastic tool! One issue that came up for me and stopped me from performing a full dashboard restoration was that in the get_folder_id_from_old_folder_url
function, response[1]
was deemed a dict
on some instances rather than a string which caused the json.loads()
call to throw a TypeError
error for me regularly.
To fix it, I added the following if statement to replace line 45
(folder_data = json.loads(response[1])
)
if isinstance(response[1],dict):
folder_dict_to_str = json.dumps(response[1])
# String to valid json
folder_data = json.loads(folder_dict_to_str)
else:
folder_data = json.loads(response[1])
Are you able to implement this or something similar to the master branch, please?
The unpacking operator used in grafanaSettings.py in the most recent version breaks compatibility with Python 2.7 as the unpacking operator (**) for EXTRA_HEADERS is not supported in versions of Python before 3.5.
So perhaps just update your README.
I've tried using the docker container to back up my grafana instance. Everything appears to work fine, but when I try extracting the resulting tar file I see the following error:
# tar xvzf 2019-06-21T16\:19\:59.tar.gz
tar (child): Cannot connect to 2019-06-21T16: resolve failed
gzip: stdin: unexpected end of file
tar: Child returned status 128
tar: Error is not recoverable: exiting now
It seems that if I extract the tar file from a directory higher than it exists, it works, but if I try to extract it from its current directory, it does not.
root@8861f06da2eb:/opt/grafana-backup-tool/_OUTPUT_# tar xvzf 2019-06-21T16\:22\:39.tar.gz
tar (child): Cannot connect to 2019-06-21T16: resolve failed
gzip: stdin: unexpected end of file
tar: Child returned status 128
tar: Error is not recoverable: exiting now
root@8861f06da2eb:/opt/grafana-backup-tool/_OUTPUT_# cd ..
root@8861f06da2eb:/opt/grafana-backup-tool# tar xvzf _OUTPUT_/2019-06-21T16\:22\:39.tar.gz
_OUTPUT_/dashboards/2019-06-21T16:22:39/
_OUTPUT_/dashboards/2019-06-21T16:22:39/VLIFWnMWk.dashboard
_OUTPUT_/dashboards/2019-06-21T16:22:39/tnvBiR4Zk.dashboard
_OUTPUT_/dashboards/2019-06-21T16:22:39/77G4tjmWk.dashboard
_OUTPUT_/dashboards/2019-06-21T16:22:39/2co7gfmZk.dashboard
_OUTPUT_/dashboards/2019-06-21T16:22:39/dashboards_201906211622.txt
_OUTPUT_/datasources/2019-06-21T16:22:39/
_OUTPUT_/folders/2019-06-21T16:22:39/
_OUTPUT_/folders/2019-06-21T16:22:39/folders_201906211622.txt
_OUTPUT_/folders/2019-06-21T16:22:39/UWX_f8WZk.folder
_OUTPUT_/folders/2019-06-21T16:22:39/_CWXfUWWz.folder
In grafana 5 when we execute backup, all folders are saved as a dashboard and when we try to restore this backup, folders are created as dashboards in the other instance.
The tool is saving the datasource without the password (encrypted or otherwise). Is it expected that the admin is supposed to manually insert the password into the datasource once it's been restored? Is anyone looking into the possibility of retrieving an encrypted password?
I ceated and added an API key as suggested in your documentation but cannot get the sript working due to authentication errors.
########################################
search dashboard in grafana:
get dashboards failed, status: 401, msg: {"message":"Basic auth failed"}
########################################
I'm using Grafana v6.1.3 (9504db8)
Any hints for me?
Regards
@ysde let me know how you want to proceed but I think these instructions should work to get it published to PyPI if you want to try and follow these steps: https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives
Hi all,
wanted to try this but doesn't get it working.
Grafana URL is using https, grafana version is 6.0.2, Api got admin rights, when executing the backup script, I got:
2019-03-20_15:55:29
search dashboard in grafana:
Traceback (most recent call last):
File "/root/grafana-backup-tool/saveDashboards.py", line 45, in
dashboards = get_all_dashboards_in_grafana()
File "/root/grafana-backup-tool/saveDashboards.py", line 15, in get_all_dashboards_in_grafana
status_and_content_of_all_dashboards = search_dashboard()
File "/root/grafana-backup-tool/dashboardApi.py", line 7, in search_dashboard
r = send_grafana_get(grafana_url + '/api/search/?type=dash-db&limit=' + search_api_limit)
TypeError: cannot concatenate 'str' and 'int' objects
Thanks in advanced.
Cheers,
Marcus
Hi,
I'am trying to use grafana-backup to backup and restore my grafana dashboards.
The backup works fine but I don't know how tu use the restore method.
I want to use it from docker.
For the backup I'am using this :
docker run --rm --name grafana-backup-tool \
-e GRAFANA_TOKEN={YOUR_GRAFANA_TOKEN} \
-e GRAFANA_URL={YOUR_GRAFANA_URL} \
-v {YOUR_BACKUP_FOLDER_ON_THE_HOST}:/opt/grafana-backup-tool/_OUTPUT_ \
ysde/docker-grafana-backup-tool
But for the restore I don't know what to do. When I look inside the Dockerfile I see that there is an ENTRYPOINT assigned to backup_grafana.sh.
thank you for your help
Restoring a dashboard fails with this error:
restoring dashboard: /tmp/tmp6drgimz0/_OUTPUT_/dashboards/202007301025/-xEOFu0Zz.dashboard
Traceback (most recent call last):
File "/usr/bin/grafana-backup", line 11, in <module>
load_entry_point('grafana-backup==1.0.0', 'console_scripts', 'grafana-backup')()
File "/usr/lib/python3.8/site-packages/grafana_backup/cli.py", line 46, in main
restore(args, settings)
File "/usr/lib/python3.8/site-packages/grafana_backup/restore.py", line 43, in main
restore_functions[ext](args, settings, file_path)
File "/usr/lib/python3.8/site-packages/grafana_backup/create_dashboard.py", line 19, in main
'folderId': get_folder_id_from_old_folder_url(content['meta']['folderUrl']),
File "/usr/lib/python3.8/site-packages/grafana_backup/dashboardApi.py", line 70, in get_folder_id_from_old_folder_url
response = get_folder(uid)
TypeError: get_folder() missing 4 required positional arguments: 'grafana_url', 'http_get_headers', 'verify_ssl', and 'debug'
Looks as if ab06386 changed get_folder
to require four args, where the rest of the code seems to call it with just one.
Hi! I am using the current master of this project and while I can successfully export datasources and folders, the export of dashboards failes like so:
python saveDashboards.py /some-folder/
search dashboard in grafana:
There are 651 dashboards:
name: :: Bitbucket
name: :: Bot Traffic
...
########################################
query dashboard uri: db/bitbucket, status: 200
Traceback (most recent call last):
File "saveDashboards.py", line 47, in <module>
get_indivisual_dashboard_setting_and_save(dashboards)
File "saveDashboards.py", line 40, in get_indivisual_dashboard_setting_and_save
save_dashboard_setting(board['title'], board['uid'], status_code_and_content[1])
File "saveDashboards.py", line 32, in save_dashboard_setting
f.write(dashboard_settings.encode('utf-8'))
TypeError: write() argument must be str, not bytes
Grafana version is 5.4.2, os is Debian 9
Even though the README states the GRAFANA_HEADERS is an optional environment varible, when i do not include it i get this error: EXTRA_HEADERS = dict(h.split(':') for h in os.getenv('GRAFANA_HEADERS').split(',') if 'GRAFANA_HEADERS' in os.environ) AttributeError: 'NoneType' object has no attribute 'split'
I also attempted to setting GRAFANA_HEADERS equal to an empty string, i get a different error here: ValueError: dictionary update sequence element #0 has length 1; 2 is required
Below is a pull request to a solution for this error.
#47
I saw PR #9 but I propose different solution: use the uri as filename, it should be filenamesafe on most filesystems...
Anyway, here is my suggestion, just in case:
diff --git a/saveDashboards.py b/saveDashboards.py
index 6e22071..2ce5d21 100644
--- a/saveDashboards.py
+++ b/saveDashboards.py
@@ -27,9 +27,10 @@ def save_dashboard_setting(file_name, dashboard_settings):
def get_indivisual_dashboard_setting_and_save(dashboards):
for board in dashboards:
status_code_and_content = get_dashboard(board['uri'])
+ file_name = re.sub('^db/','',board['uri'])
if status_code_and_content[0] == 200:
# print(status_code_and_content[1])
- save_dashboard_setting(board['title'], status_code_and_content[1])
+ save_dashboard_setting(file_name, status_code_and_content[1])
# save_dashboard_setting(board['title'], json.dumps(status_code_and_content[1]))
dashboards = get_all_dashboards_in_grafana()
There are some other errors with folders, so the above may not be the only thing that is needed.
Then I read about uid: http://docs.grafana.org/http_api/dashboard/ may be it is better to use that?
Hi!
Using grafana-backup-tool in docker I get the following error:
TimeoutError: [Errno 110] Connection timed out
trace.log
Centos 7
Grafana v6.7.0-2a2568f6pre
Grafana API token validation successful.
I would be grateful for any advice.
hi
thank you man you have a very good tool
i would like to ask you if you can add backup and restore to alerts channels
https://grafana.com/docs/http_api/alerting_notification_channels/
thanks
In my case, Grafana is sitting behind a load balancer which routes based on the Host header.
This is not an issue but a question.
So we generated an API token on one Grafana instance and used the script to migrate some dashboards. After that we accidentally deleted the API token on the instance, and keep getting unauthorized error. So I'm wondering if this token is required even after migration?
I seem to be encountering errors, but I'm not sure if it is because my Grafana instance has SSO and SSL enabled.
Error with the real URL:
[DEBUG] status: 404
Traceback (most recent call last):
File "/root/grafana-backups/scripts/src/save_dashboards.py", line 67, in <module>
(status, resp) = health_check()
File "/root/grafana-backups/scripts/src/dashboardApi.py", line 8, in health_check
return send_grafana_get(url)
File "/root/grafana-backups/scripts/src/dashboardApi.py", line 73, in send_grafana_get
log_response(r)
File "/root/grafana-backups/scripts/src/commons.py", line 16, in log_response
print("[DEBUG] body: {0}".format(resp.json()))
File "/usr/lib/python2.7/dist-packages/requests/models.py", line 651, in json
return json.loads(self.text or self.content, **kwargs)
File "/usr/lib64/python2.7/dist-packages/simplejson/__init__.py", line 505, in loads
return _default_decoder.decode(s)
File "/usr/lib64/python2.7/dist-packages/simplejson/decoder.py", line 370, in decode
obj, end = self.raw_decode(s)
File "/usr/lib64/python2.7/dist-packages/simplejson/decoder.py", line 400, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())
simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
With localhost in grafanasettings.py
grafana health: http://localhost:3000/api/health
[DEBUG] status: 200
Traceback (most recent call last):
File "/root/grafana-backups/scripts/src/save_dashboards.py", line 67, in <module>
(status, resp) = health_check()
File "/root/grafana-backups/scripts/src/dashboardApi.py", line 8, in health_check
return send_grafana_get(url)
File "/root/grafana-backups/scripts/src/dashboardApi.py", line 73, in send_grafana_get
log_response(r)
File "/root/grafana-backups/scripts/src/commons.py", line 16, in log_response
print("[DEBUG] body: {0}".format(resp.json()))
File "/usr/lib/python2.7/dist-packages/requests/models.py", line 651, in json
return json.loads(self.text or self.content, **kwargs)
File "/usr/lib64/python2.7/dist-packages/simplejson/__init__.py", line 505, in loads
return _default_decoder.decode(s)
File "/usr/lib64/python2.7/dist-packages/simplejson/decoder.py", line 370, in decode
obj, end = self.raw_decode(s)
File "/usr/lib64/python2.7/dist-packages/simplejson/decoder.py", line 400, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())
simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Getting this error. Let me know if you need more info.
Traceback (most recent call last):
File "/home/manderse/bin/grafana-backup-tool/saveDashboards.py", line 47, in
get_indivisual_dashboard_setting_and_save(dashboards)
File "/home/manderse/bin/grafana-backup-tool/saveDashboards.py", line 38, in get_indivisual_dashboard_setting_and_save
status_code_and_content = get_dashboard(board['uri'])
File "/home/manderse/bin/grafana-backup-tool/dashboardApi.py", line 11, in get_dashboard
r = send_grafana_get(grafana_url + "/api/dashboards/{0}".format(board_uri))
File "/home/manderse/bin/grafana-backup-tool/dashboardApi.py", line 67, in send_grafana_get
log_response(r)
File "/home/manderse/bin/grafana-backup-tool/commons.py", line 9, in log_response
print("body: {0}".format(resp.content.decode('utf8')))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xb0' in position 1206: ordinal not in range(128)
ubuntu@ip-172-17-0-146:~/git/grafana-backup-tool$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
ubuntu@ip-172-17-0-146:~/git/grafana-backup-tool$ printenv | grep GRAFANA
GRAFANA_URL=http://ip-172-17-0-146:3000/grafana
GRAFANA_TOKEN=***********************************
I can curl to ip-172-17-0-146:3000/grafana and get back data.
ubuntu@ip-172-17-0-146:~/git/grafana-backup-tool$ python saveDatasources.py ../dashboard_backup/
search datasources in grafana:
Traceback (most recent call last):
File "saveDatasources.py", line 27, in <module>
datasources = get_all_datasources_and_save()
File "saveDatasources.py", line 19, in get_all_datasources_and_save
datasources = json.loads(content_of_datasources)
File "/usr/lib/python2.7/json/__init__.py", line 339, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 364, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
Not sure if this tool is supposed to work against grafana version 4 aswell. If not then please just close the ticket.
Python 2.7.9
Both grafana env variables are set and correct (I know because the saveDashboards.py works like a charm)
Grafana version: 4.1.0
user@server:/github/grafana-backup-tool$ python saveDatasources.py ~/tmp
search datasources in grafana:
There are 1 datasources:
Traceback (most recent call last):
File "saveDatasources.py", line 27, in <module>
datasources = get_all_datasources_and_save()
File "saveDatasources.py", line 23, in get_all_datasources_and_save
save_datasource(datasource['name'], datasource)
TypeError: string indices must be integers
The $datasource contains only u'message'
Hello,
Thanks for the share.
I've the following error:
grafana health: https://monitoring.domain.com/api/health /home/florent/.local/lib/python2.7/site-packages/urllib3/connectionpool.py:1004: InsecureRequestWarning: Unverified HTTPS request is being made to host 'monitoring.domain.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings InsecureRequestWarning, [DEBUG] status: 200 [DEBUG] body: {u'commit': u'65dbd7cadc', u'version': u'7.0.0-c1fa1cd2pre', u'database': u'ok'} Traceback (most recent call last): File "/tmp/grafana-backup-tool/src/save_dashboards.py", line 70, in <module> is_api_support_page_param = left_ver_newer_than_right_ver(resp['version'], "6.2.0") File "/tmp/grafana-backup-tool/src/commons.py", line 6, in left_ver_newer_than_right_ver return convertVersion(current_version) > convertVersion(specefic_version) File "/tmp/grafana-backup-tool/src/commons.py", line 5, in convertVersion return int(''.join(ver.split("."))) ValueError: invalid literal for int() with base 10: '700-c1fa1cd2pre'
Any idea?
Thanks.
Florent
Hello,
I try to launch the backup_grafana.sh but I have the following error :
./backup_grafana.sh
2019-01-28_14:10:33
Traceback (most recent call last):
File "/opt/grafana-backup-tool/saveDashboards.py", line 2, in <module>
from dashboardApi import *
File "/opt/grafana-backup-tool/dashboardApi.py", line 1, in <module>
import requests, json, re
File "/usr/lib/python2.7/dist-packages/requests/__init__.py", line 80, in <module>
from . import utils
File "/usr/lib/python2.7/dist-packages/requests/utils.py", line 25, in <module>
from .compat import parse_http_list as _parse_list_header
File "/usr/lib/python2.7/dist-packages/requests/compat.py", line 94, in <module>
from urllib3.packages.ordered_dict import OrderedDict
ImportError: No module named ordered_dict
Traceback (most recent call last):
File "/opt/grafana-backup-tool/saveDatasources.py", line 2, in <module>
from dashboardApi import *
File "/opt/grafana-backup-tool/dashboardApi.py", line 1, in <module>
import requests, json, re
File "/usr/lib/python2.7/dist-packages/requests/__init__.py", line 80, in <module>
from . import utils
File "/usr/lib/python2.7/dist-packages/requests/utils.py", line 25, in <module>
from .compat import parse_http_list as _parse_list_header
File "/usr/lib/python2.7/dist-packages/requests/compat.py", line 94, in <module>
from urllib3.packages.ordered_dict import OrderedDict
ImportError: No module named ordered_dict
Traceback (most recent call last):
File "/opt/grafana-backup-tool/saveFolders.py", line 2, in <module>
from dashboardApi import *
File "/opt/grafana-backup-tool/dashboardApi.py", line 1, in <module>
import requests, json, re
File "/usr/lib/python2.7/dist-packages/requests/__init__.py", line 80, in <module>
from . import utils
File "/usr/lib/python2.7/dist-packages/requests/utils.py", line 25, in <module>
from .compat import parse_http_list as _parse_list_header
File "/usr/lib/python2.7/dist-packages/requests/compat.py", line 94, in <module>
from urllib3.packages.ordered_dict import OrderedDict
ImportError: No module named ordered_dict
tar: Removing leading `/' from member names
/tmp/dashboards/2019-01-28_14:10:33/
tar: Removing leading `/' from member names
/tmp/datasources/2019-01-28_14:10:33/
tar: Removing leading `/' from member names
/tmp/folders/2019-01-28_14:10:33/
Did someone had the same issue and/or know what should I do ?
Hi, recently I've upgraded Grafana server to version 7.0, and backup tool cannot backup dashboards from it.
Here is traceback from the container:
Backing up grafana
/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py:986: InsecureRequestWarning: Unverified HTTPS request is being made to host 'beta-grafana.xyz.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning,
grafana health: https://beta-grafana.xyz.com:443//api/health
[DEBUG] status: 200
Traceback (most recent call last):
File "./src/save_dashboards.py", line 75, in <module>
(status, resp) = health_check()
File "/opt/grafana-backup-tool/src/dashboardApi.py", line 29, in health_check
return send_grafana_get(url)
File "/opt/grafana-backup-tool/src/dashboardApi.py", line 106, in send_grafana_get
log_response(r)
File "/opt/grafana-backup-tool/src/commons.py", line 18, in log_response
print("[DEBUG] body: {0}".format(resp.json()))
File "/usr/local/lib/python3.7/site-packages/requests/models.py", line 898, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/local/lib/python3.7/json/__init__.py", line 348, in loads
return _default_decoder.decode(s)
File "/usr/local/lib/python3.7/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/local/lib/python3.7/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Hi,
What's the reason behind using the uid instead of the dashbaord title for the filename when saving the dashboard file?
Thanks
Is there any way this could be expanded to support backup/restore of users and orgs?
In my environment we have multiple organizations with different users/privileges per org.
Hey, I'm playing with the grafana/grafana:master container and it returns 6.4.0-pre
as it's version. The script chokes on that since after the splits it's still not an number 640-pre
.
Hi, I have recently noticed that tool doesn't handle Grafan API errors well.
In case of providing wrong Grafana Token, API replay with status 401
and following log is printed:
search alert channels in grafana: http://192.168.0.25:8081/api/alert-notifications
[DEBUG] status: 401
[DEBUG] body: {'message': 'Invalid API key'}
query alert channels failed, status: 401, msg: {'message': 'Invalid API key'}
But the tool works as usual, it creates empty archive and returns without errors.
Maybe it would be better to indicate such error (and probably other) with exit code and don't produce malformed archive files? It would be helpful especially when script is run automatically.
Kind regards,
Paweł
From http://docs.python-requests.org/en/master/
Note:
The use of Python 3 is highly preferred over Python 2. Consider upgrading your applications and infrastructure if you find yourself still using Python 2 in production today. If you are using Python 3, congratulations — you are indeed a person of excellent taste. —Kenneth Reitz
This tool is one of the few in my systems that still works only with python2.7, please upgrade it to support python3, as well.
It looks simple enough to do with futurize
(looks like only 'print()' is used), let me know if you prefer PR, or you'd rather hand-check it yourself.
Subject says it - I did it in my proposed fix here: #52
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.