Merge ~jacekn/charm-grafana:master into ~prometheus-charmers/charm-grafana:master

Proposed by Jacek Nykis
Status: Merged
Approved by: Alexandre Gomes
Approved revision: d3f6e4fb59641cae6d50cfe34b788fa9133edc0a
Merged at revision: e6bc20bc38df1dbedccb9dca369c11484919ce7f
Proposed branch: ~jacekn/charm-grafana:master
Merge into: ~prometheus-charmers/charm-grafana:master
Diff against target: 140 lines (+68/-43)
2 files modified
actions.yaml (+8/-2)
actions/import-dashboard (+60/-41)
Reviewer Review Type Date Requested Status
Alexandre Gomes Approve
Review via email: mp+337718@code.launchpad.net

Commit message

Rewrite import-dashboard action to support import of files on disk

Description of the change

Rewrite import-dashboard action to support import of files on disk

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Alexandre Gomes (alejdg) wrote :

+1

review: Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision e6bc20bc38df1dbedccb9dca369c11484919ce7f

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/actions.yaml b/actions.yaml
2index 81b8a67..5476855 100644
3--- a/actions.yaml
4+++ b/actions.yaml
5@@ -1,10 +1,16 @@
6 import-dashboard:
7- description: Imports a dashboard to grafana, takes dashboard argument, base64 encoded json dashboard
8+ description: |
9+ Imports dashboards to grafana. The dashboard argument contains base64
10+ encoded json dashboard. The location contains path on disk to
11+ a directory or file containing dashboards to be imported. This must
12+ exist on the unit runinng the action
13 params:
14 dashboard:
15 type: string
16 description: Contains the dashboard to be imported, in base64 encoded json format
17- required: [dashboard]
18+ location:
19+ type: string
20+ description: Path to a file or directory containing dashboards to import.
21 additionalProperties: false
22 get-admin-password:
23 description: Retrieves the admin password, either auto generated or set in config
24diff --git a/actions/import-dashboard b/actions/import-dashboard
25index d9e3477..c10596d 100755
26--- a/actions/import-dashboard
27+++ b/actions/import-dashboard
28@@ -5,7 +5,7 @@ import requests
29 import json
30 import base64
31 import traceback
32-import sys
33+import os
34 from charmhelpers.core.hookenv import (
35 config,
36 action_fail,
37@@ -16,44 +16,63 @@ from charmhelpers.core.hookenv import (
38
39 from grafana_utils import get_admin_password
40
41-action = "import-dashboard"
42-
43-passwd = get_admin_password()
44-
45-if passwd is None:
46- action_fail('Unable to retrieve password.')
47- sys.exit(0)
48-
49-port = config('port')
50-grafana = "http://localhost:%s" % (port)
51-api_auth = ('admin', passwd)
52-api_dash_import_url = "/api/dashboards/import"
53-try:
54- dashboard_data = json.loads(base64.b64decode(action_get('dashboard')).decode('utf-8'))
55-except base64.binascii.Error:
56- action_fail("Failed to base64 decode dashboard!")
57- exit(0)
58-except json.JSONDecodeError as e:
59- action_fail("Fail to json decode the dashboard: %s" % (e.msg))
60- exit(0)
61-except Exception:
62- action_fail('Unhandled exception')
63- tb = traceback.format_exc()
64- action_set(dict(traceback=tb))
65- log('Unhandled exception in action {}'.format(action))
66- print(tb)
67-
68-# Needs to be the format:
69-# { "dashboard": { dashboard },
70-# "overwrite": true } - use false here if you don't want to overwrite
71-# existing dashboards
72-
73-headers = {'Content-Type': 'application/json'}
74-r = requests.post(grafana + api_dash_import_url, auth=api_auth, headers=headers,
75- data=json.dumps(dashboard_data))
76-title = dashboard_data['dashboard']['title']
77-if r.status_code == 200:
78- action_set({"loaded": title})
79-else:
80- action_fail("Dashboard %s failed to load" % (title))
81
82+def import_dashboard(dashboard):
83+ headers = {'Content-Type': 'application/json'}
84+ import_url = 'http://localhost:{}/api/dashboards/import'.format(
85+ config('port'))
86+ passwd = get_admin_password()
87+ if passwd is None:
88+ action_fail('Unable to retrieve grafana password.')
89+ return False
90+ api_auth = ('admin', passwd)
91+ r = requests.post(import_url, auth=api_auth, headers=headers,
92+ data=json.dumps(dashboard))
93+ if r.status_code == 200:
94+ return True
95+ else:
96+ title = dashboard['dashboard']['title']
97+ action_fail('Error importing dashboard: "{}"'.format(title))
98+ return False
99+
100+
101+def import_file(path):
102+ with open(path, 'r') as f:
103+ d = f.read()
104+ try:
105+ j = json.loads(d)
106+ except json.JSONDecodeError as e:
107+ action_fail('Fail to json decode the dashboard: {}'.format(e.msg))
108+ return False
109+ return import_dashboard(j)
110+
111+
112+if action_get('dashboard'):
113+ try:
114+ d = json.loads(base64.b64decode(action_get('dashboard')).decode('utf-8'))
115+ except base64.binascii.Error:
116+ action_fail("Failed to base64 decode dashboard!")
117+ except json.JSONDecodeError as e:
118+ action_fail("Fail to json decode the dashboard: %s" % (e.msg))
119+ except Exception:
120+ action_fail('Unhandled exception, check logs')
121+ log(traceback.format_exc())
122+ import_dashboard(d)
123+
124+if action_get('location'):
125+ path = action_get('location')
126+ if not os.path.exists(path):
127+ action_fail('Provided path does not exist on unit: {}'.format(path))
128+ elif os.path.isfile(path):
129+ import_file(path)
130+ elif os.path.isdir(path):
131+ f_count = 0
132+ s_count = 0
133+ for f in os.listdir(path):
134+ if import_file(os.path.join(path, f)):
135+ s_count += 1
136+ else:
137+ f_count += 1
138+ action_set({'summary': 'Found {}. Imported: {}. Failed: {}'.format(s_count+f_count, s_count, f_count)})
139+ if f_count > 0:
140+ action_fail('Number of dashboards that failed to impor: {}'.format(f_count))

Subscribers

People subscribed via source and target branches