grafana-api 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a8db882d27b2ce8806d6eb17c2476610847d3415
4
- data.tar.gz: 2a793a77bb449405582ae6b2a6cf44ea80986a1e
3
+ metadata.gz: eb679815babc5bcb0c1f9aaae398ad9a0db96528
4
+ data.tar.gz: 448445928c252bbef2fcad51150b1c4df111fbb2
5
5
  SHA512:
6
- metadata.gz: 5485c5c075a442b7bbddbdeb3b4a4bd4c611c869136294d237c2d03c2efdf6d40e569121ff255509f4249fffee52ca254779be26bd2cc5ed1216ef3a49c4de91
7
- data.tar.gz: 633e33e84f22a60bef80c52640887b89b57d26e9aeefaa7c74ada8166e4b12653dae793607c93db218fc6ffdb71ac7b80fbe1f4457b523da3c237cecf2e5d6e6
6
+ metadata.gz: 8e51435dfa74cdbc8e0a9d89a70415a37076c6e04d4dd44c645f0c549d401418b04180227afdceede958509403925a884e24548b9a6a7a306a325c072cda94ae
7
+ data.tar.gz: e6ee4a7fea2f7be1d8cf6be2d2261c439995a5aafc07dc1ffe5937c2845892b87ec01c4433a01d023fa50e603e74f77ae3075456050847cc478e8cf98862eaab
@@ -0,0 +1,2 @@
1
+
2
+ require 'grafana/client.rb'
@@ -0,0 +1,70 @@
1
+
2
+ module Grafana
3
+
4
+ module Admin
5
+
6
+ def get_admin_settings()
7
+ endpoint = "/api/admin/settings"
8
+ @logger.info("Getting admin settings (GET #{endpoint})") if @debug
9
+ return get_request(endpoint)
10
+ end
11
+
12
+ def update_user_permissions(id, perm)
13
+
14
+ valid_perms = ['Viewer','Editor','Read Only Editor','Admin']
15
+
16
+ if perm.class.to_s == "String" && !valid_perms.include?(perm)
17
+ @logger.warn("Basic user permissions include: #{valid_perms.join(',')}") if @debug
18
+ return false
19
+ elsif perm.class.to_s == "Hash" &&
20
+ ( !perm.has_key?('isGrafanaAdmin') || ![true,false].include?(perm['isGrafanaAdmin']) )
21
+ @logger.warn("Grafana admin permission must be either true or false") if @debug
22
+ return false
23
+ end
24
+
25
+ @logger.info("Updating user ID #{id} permissions") if @debug
26
+
27
+ if perm.class.to_s == 'Hash'
28
+ endpoint = "/api/admin/users/#{id}/permissions"
29
+ @logger.info("Updating user ID #{id} permissions (PUT #{endpoint})") if @debug
30
+ return put_request(endpoint, {"isGrafanaAdmin" => perm['isGrafanaAdmin']}.to_json)
31
+ else
32
+ org = self.get_current_org()
33
+ endpoint = "/api/orgs/#{org['id']}/users/#{id}"
34
+ @logger.info("Updating user ID #{id} permissions (PUT #{endpoint})") if @debug
35
+ user = {
36
+ 'name' => org['name'],
37
+ 'orgId' => org['id'],
38
+ 'role' => perm.downcase.capitalize
39
+ }
40
+ return patch_request(endpoint, user.to_json)
41
+ end
42
+ end
43
+
44
+ def delete_user(user_id)
45
+ if user_id == 1
46
+ @logger.warn("Can't delete user ID #{user_id} (admin user)") if @debug
47
+ return false
48
+ end
49
+ endpoint = "/api/admin/users/#{user_id}"
50
+ @logger.info("Deleting user ID #{user_id} (DELETE #{endpoint})") if @debug
51
+ return delete_request(endpoint)
52
+ end
53
+
54
+ def create_user(properties={})
55
+ endpoint = "/api/admin/users"
56
+ @logger.info("Creating user: #{properties['name']}") if @debug
57
+ @logger.info("Data: #{properties.to_s}") if @debug
58
+ return post_request(endpoint, properties.to_json)
59
+ end
60
+
61
+ def update_user_pass(user_id,password)
62
+ endpoint = " /api/admin/users/#{user_id}/#{password}"
63
+ @logger.info("Updating password for user ID #{user_id} (PUT #{endpoint})") if @debug
64
+ return put_request(endpoint,properties)
65
+ end
66
+
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,100 @@
1
+
2
+ require 'rest-client'
3
+ require 'json'
4
+ require 'logger'
5
+
6
+ module Grafana
7
+
8
+ require_relative 'http_request'
9
+ require_relative 'user'
10
+ require_relative 'users'
11
+ require_relative 'datasource'
12
+ require_relative 'organization'
13
+ require_relative 'organizations'
14
+ require_relative 'dashboard'
15
+ require_relative 'dashboard_template'
16
+ require_relative 'snapshot'
17
+ require_relative 'frontend'
18
+ require_relative 'login'
19
+ require_relative 'admin'
20
+ require_relative 'version'
21
+
22
+ class Client
23
+
24
+ attr_reader :debug, :session_cookies, :headers, :logger, :api_instance
25
+
26
+ include Grafana::HttpRequest
27
+ include Grafana::User
28
+ include Grafana::Users
29
+ include Grafana::Datasource
30
+ include Grafana::Organization
31
+ include Grafana::Organizations
32
+ include Grafana::Dashboard
33
+ include Grafana::DashboardTemplate
34
+ include Grafana::Snapshot
35
+ include Grafana::Frontend
36
+ include Grafana::Login
37
+ include Grafana::Admin
38
+
39
+ def initialize(host="localhost", port=3000, user='admin', pass='', settings={})
40
+
41
+ if settings.has_key?('timeout') && settings['timeout'].to_i <= 0
42
+ settings['timeout'] = 5
43
+ end
44
+
45
+ if settings.has_key?('open_timeout') && settings['open_timeout'].to_i <= 0
46
+ settings['open_timeout'] = 5
47
+ end
48
+
49
+ if settings.has_key?('headers') && settings['headers'].class.to_s != 'Hash'
50
+ settings['headers'] = {}
51
+ end
52
+
53
+ proto = ( settings.has_key?('ssl') && settings['ssl'] == true ? 'https' : 'http')
54
+
55
+ @logger.info("Initializing API client #{proto}://#{host}:#{port}") if @debug
56
+ @logger.info("Options: #{options}") if @debug
57
+
58
+ @api_instance = RestClient::Resource.new(
59
+ "#{proto}://#{host}:#{port}",
60
+ :timeout => settings['timeout'],
61
+ :open_timeout => settings['open_timeout'],
62
+ :headers => settings['headers']
63
+ )
64
+ @debug = (settings['debug'] ? true : false)
65
+ @logger = Logger.new(STDOUT)
66
+ @headers = nil
67
+
68
+ self.login(user, pass)
69
+ return self
70
+ end
71
+
72
+ def login(user='admin',pass='admin')
73
+ @logger.info("Attempting to establish user session") if @debug
74
+ request_data = {'User' => user, 'Password' => pass}
75
+ begin
76
+ resp = @api_instance['/login'].post(
77
+ request_data.to_json,
78
+ {:content_type => 'application/json; charset=UTF-8'}
79
+ )
80
+ @session_cookies = resp.cookies
81
+ if resp.code.to_i == 200
82
+ @headers = {
83
+ :content_type => 'application/json; charset=UTF-8',
84
+ :cookies => @session_cookies
85
+ }
86
+ return true
87
+ else
88
+ return false
89
+ end
90
+ rescue => e
91
+ @logger.error("Error running POST request on /login: #{e}") if @debug
92
+ @logger.error("Request data: #{request_data.to_json}") if @debug
93
+ return false
94
+ end
95
+ @logger.info("User session initiated") if @debug
96
+ end
97
+
98
+ end # End of Client class
99
+
100
+ end # End of GrafanaApi module
@@ -0,0 +1,60 @@
1
+
2
+ module Grafana
3
+
4
+ module Dashboard
5
+
6
+ def create_slug(text)
7
+ if text =~ /\s/
8
+ if text =~ /-/
9
+ text = text.gsub(/\s+/, "").downcase
10
+ else
11
+ text = text.gsub(/\s+/, "-").downcase
12
+ end
13
+ end
14
+ return text
15
+ end
16
+
17
+ def get_dashboard(name='')
18
+ endpoint = "/api/dashboards/db/#{name}"
19
+ name = self.create_slug(name)
20
+ @logger.info("Attempting to get dashboard (GET /api/dashboards/db/#{name})") if @debug
21
+ return get_request(endpoint)
22
+ end
23
+
24
+ def create_dashboard(properties={})
25
+ endpoint = "/api/dashboards/db"
26
+ dashboard = self.build_template(properties)
27
+ @logger.info("Creating dashboard: #{properties['title']} (POST /api/dashboards/db)") if @debug
28
+ return post_request(endpoint, dashboard)
29
+ end
30
+
31
+ def delete_dashboard(name)
32
+ name = self.create_slug(name)
33
+ endpoint = "/api/dashboards/db/#{name}"
34
+ @logger.info("Deleting dahsboard ID #{id} (DELETE #{endpoint})") if @debug
35
+ return delete_request(endpoint)
36
+ end
37
+
38
+ def get_home_dashboard()
39
+ endpoint = "/api/dashboards/home"
40
+ @logger.info("Attempting to get home dashboard (GET #{endpoint})") if @debug
41
+ return get_request(endpoint)
42
+ end
43
+
44
+ def get_dashboard_tags()
45
+ endpoint = "/api/dashboards/tags"
46
+ @logger.info("Attempting to get dashboard tags(GET #{endpoint})") if @debug
47
+ return get_request(endpoint)
48
+ end
49
+
50
+ def search_dashboards(params={})
51
+ params['query'] = (params['query'].length >= 1 ? CGI::escape(params['query']) : '' )
52
+ params['starred'] = (params['starred'] ? 'true' : 'false')
53
+ endpoint = "/api/search/?query=#{params['query']}&starred=#{params['starred']}&tag=#{params['tags']}"
54
+ @logger.info("Attempting to search for dashboards (GET #{endpoint})") if @debug
55
+ return get_request(endpoint)
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,224 @@
1
+
2
+ module Grafana
3
+
4
+ module DashboardTemplate
5
+
6
+ # CloudWatch Namespaces, Dimensions and Metrics Reference:
7
+ # http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html
8
+ @@cw_dimensions = []
9
+
10
+
11
+ def build_template(params={})
12
+
13
+ if !params.has_key?('from')
14
+ params['from'] = 'now-2h'
15
+ end
16
+ if !params.has_key?('to')
17
+ params['to'] = 'now'
18
+ end
19
+ if params['title'] == ''
20
+ return false
21
+ end
22
+
23
+ rows = []
24
+ params['panels'].each do |panel|
25
+ rows.push(self.build_panel(panel))
26
+ end
27
+
28
+ tpl = %q[
29
+ {
30
+ "dashboard": {
31
+ "id": null,
32
+ "title": "%{title}",
33
+ "originalTitle": "%{title}",
34
+ "annotations": {
35
+ "list": []
36
+ },
37
+ "hideControls": false,
38
+ "timezone": "browser",
39
+ "editable": true,
40
+ "rows": [
41
+ %{rows}
42
+ ],
43
+ "time": {
44
+ "from": "%{from}",
45
+ "to": "%{to}"
46
+ },
47
+ "timepicker": {
48
+ "collapse": false,
49
+ "enable": true,
50
+ "notice": false,
51
+ "now": true,
52
+ "refresh_intervals": [
53
+ "5s",
54
+ "10s",
55
+ "30s",
56
+ "1m",
57
+ "5m",
58
+ "15m",
59
+ "30m",
60
+ "1h",
61
+ "2h",
62
+ "1d"
63
+ ],
64
+ "status": "Stable",
65
+ "time_options": [
66
+ "5m",
67
+ "15m",
68
+ "1h",
69
+ "6h",
70
+ "12h",
71
+ "24h",
72
+ "2d",
73
+ "7d",
74
+ "30d"
75
+ ],
76
+ "type": "timepicker"
77
+ },
78
+ "tags": ["api-templated"],
79
+ "templating": {
80
+ "list": []
81
+ },
82
+ "schemaVersion": 7,
83
+ "sharedCrosshair": false,
84
+ "style": "dark",
85
+ "version": 1,
86
+ "links": []
87
+ },
88
+ "overwrite": false
89
+ }
90
+ ]
91
+
92
+ return tpl % {
93
+ title: params['title'],
94
+ from: params['from'],
95
+ to: params['to'],
96
+ rows: rows.join(',')
97
+ }
98
+
99
+ end
100
+
101
+
102
+ def build_panel(params={})
103
+
104
+ panel = %q[
105
+ {
106
+ "collapse": false,
107
+ "editable": true,
108
+ "height": "250px",
109
+ "panels": [
110
+ {
111
+ "aliasColors": {},
112
+ "bars": false,
113
+ "datasource": "%{datasource}",
114
+ "editable": true,
115
+ "error": false,
116
+ "fill": 1,
117
+ "grid": {
118
+ "leftLogBase": 1,
119
+ "leftMax": null,
120
+ "leftMin": null,
121
+ "rightLogBase": 1,
122
+ "rightMax": null,
123
+ "rightMin": null,
124
+ "threshold1": null,
125
+ "threshold1Color": "rgba(216, 200, 27, 0.27)",
126
+ "threshold2": null,
127
+ "threshold2Color": "rgba(234, 112, 112, 0.22)"
128
+ },
129
+ "legend": {
130
+ "avg": false,
131
+ "current": false,
132
+ "max": false,
133
+ "min": false,
134
+ "show": true,
135
+ "total": false,
136
+ "values": false
137
+ },
138
+ "lines": true,
139
+ "linewidth": 2,
140
+ "links": [],
141
+ "nullPointMode": "connected",
142
+ "percentage": false,
143
+ "pointradius": 5,
144
+ "points": false,
145
+ "renderer": "flot",
146
+ "seriesOverrides": [],
147
+ "span": 12,
148
+ "stack": false,
149
+ "steppedLine": false,
150
+ "targets": [
151
+ %{targets}
152
+ ],
153
+ "timeFrom": null,
154
+ "timeShift": null,
155
+ "title": "%{graph_title}",
156
+ "tooltip": {
157
+ "shared": true,
158
+ "value_type": "cumulative"
159
+ },
160
+ "type": "graph",
161
+ "x-axis": true,
162
+ "y-axis": true,
163
+ "y_formats": [
164
+ "short",
165
+ "short"
166
+ ]
167
+ }
168
+ ],
169
+ "title": "Row"
170
+ }
171
+ ]
172
+
173
+ targets = []
174
+ params['targets'].each do |t|
175
+ targets.push(self.build_target(t))
176
+ end
177
+
178
+
179
+ return panel % {
180
+ datasource: params['datasource'],
181
+ graph_title: params['graph_title'],
182
+ targets: targets.join(',')
183
+ }
184
+
185
+
186
+ end
187
+
188
+
189
+ def build_target(params={})
190
+
191
+ target = %q[
192
+ {
193
+ "alias": "%{legend_alias}",
194
+ "dimensions": {
195
+ "%{dimension_name}": "%{dimension_value}"
196
+ },
197
+ "metricName": "%{metric_name}",
198
+ "namespace": "%{namespace}",
199
+ "period": 60,
200
+ "query": "",
201
+ "refId": "A",
202
+ "region": "%{region}",
203
+ "statistics": [
204
+ "Maximum"
205
+ ],
206
+ "timeField": "@timestamp"
207
+ }
208
+ ]
209
+
210
+ return target % {
211
+ metric_name: params['metric_name'],
212
+ namespace: params['namespace'],
213
+ dimension_name: params['dimension_name'],
214
+ dimension_value: params['dimension_value'],
215
+ region: params['region'],
216
+ legend_alias: params['legend_alias'],
217
+ }
218
+
219
+ end
220
+
221
+ end
222
+
223
+ end
224
+
@@ -0,0 +1,64 @@
1
+
2
+ module Grafana
3
+
4
+ module Datasource
5
+
6
+ def get_cw_namespaces(datasource_id)
7
+ endpoint = "/api/datasources/proxy/#{datasource_id}"
8
+ @logger.info("Getting data source namespaces (POST /api/datasources/proxy/#{datasource_id})") if @debug
9
+ return post_request(endpoint, {"action" => "__GetNamespaces"}.to_json)
10
+ end
11
+
12
+ def get_data_sources()
13
+ endpoint = "/api/datasources"
14
+ @logger.info("Attempting to get existing data sources (GET #{endpoint})") if @debug
15
+ data_sources = get_request(endpoint)
16
+ if !data_sources
17
+ return false
18
+ end
19
+ data_source_map = {}
20
+ data_sources.each { |ds|
21
+ data_source_map[ds['id']] = ds
22
+ }
23
+ return data_source_map
24
+ end
25
+
26
+ def get_data_source(id)
27
+ endpoint = "/api/datasources/#{id}"
28
+ @logger.info("Attempting to get existing data source ID #{id}") if @debug
29
+ return get_request(endpoint)
30
+ end
31
+
32
+ def update_data_source(id, ds={})
33
+ existing_ds = self.get_data_source(id)
34
+ ds = existing_ds.merge(ds)
35
+ endpoint = "/api/datasources/#{id}"
36
+ @logger.info("Updating data source ID #{id}") if @debug
37
+ return put_request(endpoint, ds.to_json)
38
+ end
39
+
40
+ def create_data_source(ds={})
41
+ if ds == {} || !ds.has_key?('name') || !ds.has_key?('database')
42
+ @logger.error("Error: missing 'name' and 'database' values!") if @debug
43
+ return false
44
+ end
45
+ endpoint = "/api/datasources"
46
+ @logger.info("Creating data source: #{ds['name']} (database: #{ds['database']})") if @debug
47
+ return post_request(endpoint, ds.to_json)
48
+ end
49
+
50
+ def delete_data_source(id)
51
+ endpoint = "/api/datasources/#{id}"
52
+ @logger.info("Deleting data source #{id} (DELETE #{endpoint})") if @debug
53
+ return delete_request(endpoint)
54
+ end
55
+
56
+ def get_available_data_source_types()
57
+ endpoint = '/api/datasources/plugins'
58
+ @logger.info("Attempting to get existing data source types (GET #{endpoint})") if @debug
59
+ return get_request(endpoint)
60
+ end
61
+
62
+ end
63
+
64
+ end
@@ -0,0 +1,13 @@
1
+ module Grafana
2
+
3
+ module Frontend
4
+
5
+ def get_frontend_settings()
6
+ endpoint = "/api/frontend/settings"
7
+ @logger.info("Getting frontend settings (GET #{endpoint})") if @debug
8
+ return get_request(endpoint)
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,66 @@
1
+ module Grafana
2
+
3
+ module HttpRequest
4
+
5
+ def get_request(endpoint)
6
+ @logger.info("Running: Grafana::HttpRequest::#{__method__} on #{endpoint}") if @debug
7
+ return _issue_request('GET', endpoint)
8
+ end
9
+
10
+ def post_request(endpoint, postdata={})
11
+ @logger.info("Running: Grafana::HttpRequest::#{__method__} on #{endpoint}") if @debug
12
+ return _issue_request('POST', endpoint, postdata)
13
+ end
14
+
15
+ def put_request(endpoint, putdata={})
16
+ @logger.info("Running: Grafana::HttpRequest::#{__method__} on #{endpoint}") if @debug
17
+ return _issue_request('PUT', endpoint, putdata)
18
+ end
19
+
20
+ def delete_request(endpoint)
21
+ @logger.info("Running: Grafana::HttpRequest::#{__method__} on #{endpoint}") if @debug
22
+ return _issue_request('DELETE', endpoint)
23
+ end
24
+
25
+ def patch_request(endpoint, patchdata={})
26
+ @logger.info("Running: Grafana::HttpRequest::#{__method__} on #{endpoint}") if @debug
27
+ return _issue_request('PATCH', endpoint, patchdata)
28
+ end
29
+
30
+ def _issue_request(method_type='GET', endpoint='/', data={})
31
+
32
+ begin
33
+ resp = nil
34
+ case method_type.upcase
35
+ when 'GET'
36
+ resp = @api_instance[endpoint].get(@headers)
37
+ when 'POST'
38
+ resp = @api_instance[endpoint].patch(data,@headers)
39
+ when 'PATCH'
40
+ resp = @api_instance[endpoint].patch(data,@headers)
41
+ when 'PUT'
42
+ resp = @api_instance[endpoint].patch(data,@headers)
43
+ when 'DELETE'
44
+ resp = @api_instance[endpoint].patch(@headers)
45
+ else
46
+ @logger.error("Error: #{__method__} is not a valid request method.") if @debug
47
+ return false
48
+ end
49
+
50
+ if (resp.code.to_i >= 200 && resp.code.to_i <= 299) || (resp.code.to_i >= 400 && resp.code.to_i <= 499)
51
+ return JSON.parse(resp.body)
52
+ else
53
+ @logger.error("#{__method__} on #{endpoint} failed: HTTP #{resp.code} - #{resp.body}") if @debug
54
+ return false
55
+ end
56
+
57
+ rescue => e
58
+ @logger.error("Error: #{__method__} #{endpoint} error: #{e}") if @debug
59
+ return false
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,13 @@
1
+ module Grafana
2
+
3
+ module Login
4
+
5
+ def ping_session()
6
+ endpoint = "/api/login/ping"
7
+ @logger.info("Pingning current session (GET #{endpoint})") if @debug
8
+ return get_request(endpoint)
9
+
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,33 @@
1
+
2
+ module Grafana
3
+
4
+ module Organization
5
+
6
+ def get_current_org()
7
+ endpoint = "/api/org"
8
+ @logger.info("Getting current organization (GET #{endpoint})") if @debug
9
+ return get_request(endpoint)
10
+ end
11
+
12
+ def update_current_org(properties={})
13
+ endpoint = "/api/org"
14
+ @logger.info("Updating current organization (PUT #{endpoint})") if @debug
15
+ return put_request(endpoint, properties)
16
+ end
17
+
18
+ def get_current_org_users()
19
+ endpoint = "/api/org/users"
20
+ @logger.info("Getting organization users (GET #{endpoint})") if @debug
21
+ return get_request(endpoint)
22
+ end
23
+
24
+ def add_user_to_current_org(properties={})
25
+ endpoint = "/api/org/users"
26
+ @logger.info("Adding user to current organization (POST #{endpoint})") if @debug
27
+ return post_request(endpoint, properties)
28
+ end
29
+
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,46 @@
1
+
2
+ module Grafana
3
+
4
+ module Organizations
5
+
6
+ def get_all_orgs()
7
+ endpoint = "/api/orgs"
8
+ @logger.info("Getting all organizations (GET #{endpoint})") if @debug
9
+ return get_request(endpoint)
10
+ end
11
+
12
+
13
+ def update_org(org_id, properties={})
14
+ endpoint = "/api/orgs/#{org_id}"
15
+ @logger.info("Updating orgnaization ID #{org_id} (POST #{endpoint})") if @debug
16
+ return post_request(endpoint, properties)
17
+ end
18
+
19
+ def get_org_users(org_id)
20
+ endpoint = "/api/orgs/#{org_id}/users"
21
+ @logger.info("Getting users in orgnaization ID #{org_id} (GET #{endpoint})") if @debug
22
+ return get_request(endpoint)
23
+ end
24
+
25
+
26
+ def add_user_to_org(org_id, user={})
27
+ endpoint = "/api/orgs/#{org_id}/users"
28
+ @logger.info("Adding user to orgnaization ID #{org_id} (POST #{endpoint})") if @debug
29
+ return post_request(endpoint, user)
30
+ end
31
+
32
+ def update_org_user(org_id, user_id, properties={})
33
+ endpoint = "/api/orgs/#{org_id}/users/#{user_id}"
34
+ @logger.info("Updating user #{user_id} in organization #{org_id} (PATCH #{endpoint})") if @debug
35
+ return patch_request(endpoint, properties)
36
+ end
37
+
38
+ def delete_user_from_org(org_id, user_id)
39
+ endpoint = "/api/orgs/#{org_id}/users/#{user_id}"
40
+ @logger.info("Deleting user #{user_id} in organization #{org_id} (DELETE #{endpoint})") if @debug
41
+ return delete_request(endpoint)
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,25 @@
1
+ module Grafana
2
+
3
+ module Snapshot
4
+
5
+ def get_snapshot(key)
6
+ endpoint = "/api/snapshot/#{key}"
7
+ @logger.info("Getting frontend settings (GET #{endpoint})") if @debug
8
+ return get_request(endpoint)
9
+ end
10
+
11
+ def create_snapshot(dashboard={})
12
+ endpoint = "/api/snapshot"
13
+ @logger.info("Creating dashboard snapshot (POST #{endpoint})") if @debug
14
+ return post_request(endpoint, dashboard)
15
+ end
16
+
17
+ def delete_snapshot(key)
18
+ endpoint = "/api/snapshots-delete/#{key}"
19
+ @logger.info("Deleting snapshot ID #{key} (GET #{endpoint})") if @debug
20
+ return delete_request(endpoint)
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,44 @@
1
+
2
+ module Grafana
3
+
4
+ module User
5
+
6
+ def get_current_user()
7
+ endpoint = "/api/user"
8
+ @logger.info("Getting user current user (GET #{endpoint})") if @debug
9
+ return get_request(endpoint)
10
+ end
11
+
12
+ def update_current_user_pass(properties={})
13
+ endpoint = "/api/user/password"
14
+ @logger.info("Updating current user password (PUT #{endpoint})") if @debug
15
+ return put_request(endpoint,properties)
16
+ end
17
+
18
+ def switch_current_user_org(org_id)
19
+ endpoint = "/api/user/using/#{org_id}"
20
+ @logger.info("Switching current user to Org ID #{id} (GET #{endpoint})") if @debug
21
+ return post_request(endpoint, {})
22
+ end
23
+
24
+ def get_current_user_orgs()
25
+ endpoint = "/api/user/orgs"
26
+ @logger.info("Getting current user organizations (GET #{endpoint})") if @debug
27
+ return get_request(endpoint)
28
+ end
29
+
30
+ def add_dashboard_star(dashboard_id)
31
+ endpoint = "/api/user/stars/dashboard/#{dashboard_id}"
32
+ @logger.info("Adding start to dashboard ID #{dashboard_id} (GET #{endpoint})") if @debug
33
+ return post_request(endpoint, {})
34
+ end
35
+
36
+ def remove_dashboard_star(dashboard_id)
37
+ endpoint = "/api/user/stars/dashboard/#{dashboard_id}"
38
+ @logger.info("Deleting start on dashboard ID #{dashboard_id} (GET #{endpoint})") if @debug
39
+ return delete_request(endpoint)
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,51 @@
1
+
2
+ module Grafana
3
+
4
+ module Users
5
+
6
+ def get_all_users()
7
+ endpoint = "/api/users"
8
+ @logger.info("Getting all users (GET #{endpoint})") if @debug
9
+ return get_request(endpoint)
10
+ end
11
+
12
+ def get_user_by_id(id)
13
+ endpoint = "/api/users/#{id}"
14
+ @logger.info("Getting user ID #{id} (GET #{endpoint})") if @debug
15
+ return get_request(endpoint)
16
+ end
17
+
18
+ def search_for_users_by(search={})
19
+ all_users = self.get_all_users()
20
+ key, value = search.first
21
+ @logger.info("Searching for users matching #{key} = #{value}") if @debug
22
+ users = []
23
+ all_users.each do |u|
24
+ if u[key] && u[key] == value
25
+ users.push(u)
26
+ end
27
+ end
28
+ return (users.length >= 1 ? users : false)
29
+ end
30
+
31
+ def update_user_info(id, properties={})
32
+ endpoint = "/api/users/#{id}"
33
+ @logger.info("Updating user ID #{id}") if @debug
34
+ existing_user = self.get_user(id)
35
+ if !existing_user
36
+ @logger.error("User #{id} does not exist") if @debug
37
+ return false
38
+ end
39
+ properties = existing_user.merge(properties)
40
+ return put_request(endpoint,properties.to_json)
41
+ end
42
+
43
+ def get_user_orgs(userid)
44
+ endpoint = "/api/users/#{userid}/orgs"
45
+ @logger.info("Getting organizations for user #{id} (GET #{endpoint})") if @debug
46
+ return get_request(endpoint)
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,3 @@
1
+ module Grafana
2
+ VERSION = "0.1.0"
3
+ end
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grafana-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alain Lefebvre
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-13 00:00:00.000000000 Z
11
+ date: 2015-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.7'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.7'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rest-client
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.8'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.8'
41
41
  description: A simple wrapper for the Grafana HTTP API
@@ -44,7 +44,21 @@ executables: []
44
44
  extensions: []
45
45
  extra_rdoc_files: []
46
46
  files:
47
- - lib/grafana-api.rb
47
+ - lib/grafana.rb
48
+ - lib/grafana/admin.rb
49
+ - lib/grafana/client.rb
50
+ - lib/grafana/dashboard.rb
51
+ - lib/grafana/dashboard_template.rb
52
+ - lib/grafana/datasource.rb
53
+ - lib/grafana/frontend.rb
54
+ - lib/grafana/http_request.rb
55
+ - lib/grafana/login.rb
56
+ - lib/grafana/organization.rb
57
+ - lib/grafana/organizations.rb
58
+ - lib/grafana/snapshot.rb
59
+ - lib/grafana/user.rb
60
+ - lib/grafana/users.rb
61
+ - lib/grafana/version.rb
48
62
  homepage: http://github.com/lightspeedretail/ruby-grafana-api
49
63
  licenses:
50
64
  - MIT
@@ -55,18 +69,18 @@ require_paths:
55
69
  - lib
56
70
  required_ruby_version: !ruby/object:Gem::Requirement
57
71
  requirements:
58
- - - '>='
72
+ - - ">="
59
73
  - !ruby/object:Gem::Version
60
74
  version: '0'
61
75
  required_rubygems_version: !ruby/object:Gem::Requirement
62
76
  requirements:
63
- - - '>='
77
+ - - ">="
64
78
  - !ruby/object:Gem::Version
65
79
  version: '0'
66
80
  requirements: []
67
81
  rubyforge_project:
68
- rubygems_version: 2.0.14
82
+ rubygems_version: 2.4.6
69
83
  signing_key:
70
84
  specification_version: 4
71
- summary: Grafana API Wrapper
85
+ summary: Grafana HTTP API Wrapper
72
86
  test_files: []
@@ -1,355 +0,0 @@
1
- class GrafanaApi
2
-
3
- require 'rest-client'
4
- require 'json'
5
- require 'logger'
6
-
7
- attr_accessor :debug, :session_cookies, :headers
8
-
9
- def initialize(host="localhost", port=3000, debug=false)
10
- @api_instance = RestClient::Resource.new("http://#{host}:#{port}")
11
- @debug = debug
12
- @logger = Logger.new(STDOUT)
13
- @headers = nil
14
- end
15
-
16
- def login(user='admin',pass='admin')
17
- @logger.info("Attempting to establish user session") if @debug
18
- request_data = {'User' => user, 'Password' => pass}
19
- begin
20
- resp = @api_instance['/login'].post(
21
- request_data.to_json,
22
- {:content_type => 'application/json; charset=UTF-8'}
23
- )
24
- @session_cookies = resp.cookies
25
- if resp.code.to_i == 200
26
- @headers = {
27
- :content_type => 'application/json; charset=UTF-8',
28
- :cookies => @session_cookies
29
- }
30
- return true
31
- else
32
- return false
33
- end
34
- rescue => e
35
- @logger.error("Error running POST request on /login: #{e}") if @debug
36
- @logger.error("Request data: #{request_data.to_json}") if @debug
37
- return false
38
- end
39
- @logger.info("User session initiated") if @debug
40
- end
41
-
42
-
43
-
44
- def get_user(id)
45
- @logger.info("Getting user ID #{id} (GET /api/users/#{id})") if @debug
46
- begin
47
- resp = @api_instance["/api/users/#{id}"].get(@headers)
48
- if resp.code.to_i == 200
49
- return JSON.parse(resp.body)
50
- else
51
- @logger.error("Could not get user: #{resp.body}") if @debug
52
- return false
53
- end
54
- rescue => e
55
- @logger.error("Could not get user: #{e}") if @debug
56
- return false
57
- end
58
- end
59
-
60
- def get_users()
61
- @logger.info("Getting all users (GET /api/users)") if @debug
62
- begin
63
- resp = @api_instance['/api/users'].get(@headers)
64
- if resp.code.to_i == 200
65
- return JSON.parse(resp.body)
66
- else
67
- @logger.error("Could not get list of users: #{resp.body}") if @debug
68
- return false
69
- end
70
- rescue => e
71
- @logger.error("Could not get list of users: #{e}") if @debug
72
- return false
73
- end
74
- end
75
-
76
- def search_for_users_by(search={})
77
- all_users = self.get_users()
78
- key, value = search.first
79
- @logger.info("Searching for users matching #{key} = #{value}") if @debug
80
- users = []
81
- all_users.each do |u|
82
- if u[key] && u[key] == value
83
- users.push(u)
84
- end
85
- end
86
- return (users.length >= 1 ? users : false)
87
- end
88
-
89
- def create_user(properties={})
90
- @logger.info("Creating user: #{properties['name']}") if @debug
91
- @logger.info("Data: #{properties.to_s}") if @debug
92
- begin
93
- resp = @api_instance["/api/admin/users"].post(
94
- properties.to_json,
95
- @headers
96
- )
97
- result = JSON.parse(resp.body)
98
- if resp.code.to_i == 200
99
- @logger.info(resp.body) if @debug
100
- return true
101
- else
102
- @logger.error("Data source could not be created: #{resp.body}") if @debug
103
- return false
104
- end
105
- rescue => e
106
- @logger.error("Error creating data source: #{e}") if @debug
107
- return false
108
- end
109
- end
110
-
111
- def update_user_info(id, properties={})
112
- @logger.info("Updating user ID #{id}") if @debug
113
- begin
114
- existing_user = self.get_user(id)
115
- if !existing_user
116
- @logger.error("User #{id} does not exist") if @debug
117
- return false
118
- end
119
- properties = existing_user.merge(properties)
120
- resp = @api_instance["/api/users/#{id}"].put(
121
- properties.to_json,
122
- @headers
123
- )
124
- if resp.code.to_i == 200
125
- return JSON.parse(resp.body)
126
- else
127
- @logger.error("Could not update user (HTTP #{resp.code}: #{resp.body})") if @debug
128
- return false
129
- end
130
- rescue => e
131
- @logger.error("Could not update user: #{e}") if @debug
132
- return false
133
- end
134
- end
135
-
136
- def update_user_permissions(id, perm)
137
-
138
- valid_perms = ['Viewer','Editor','Read Only Editor','Admin']
139
-
140
- if perm.class.to_s == "String" &&
141
- !valid_perms.include?(perm)
142
- @logger.warn("Basic user permissions include: #{valid_perms.join(',')}") if @debug
143
- return false
144
- elsif perm.class.to_s == "Hash" &&
145
- (!perm.has_key?('isGrafanaAdmin') ||
146
- ![true,false].include?(perm['isGrafanaAdmin']) )
147
- @logger.warn("Grafana admin permission must be either true or false") if @debug
148
- return false
149
- end
150
-
151
- @logger.info("Updating user ID #{id} permissions") if @debug
152
- begin
153
- if perm.class.to_s == 'Hash'
154
- resp = @api_instance["/api/admin/users/#{id}/permissions"].put(
155
- {"isGrafanaAdmin" => perm['isGrafanaAdmin']}.to_json,
156
- @headers
157
- )
158
- else
159
- org = self.get_current_org()
160
- resp = @api_instance["/api/orgs/#{org['id']}/users/#{id}"].patch(
161
- { 'name' => org['name'], 'orgId' => org['id'],
162
- 'role' => perm.downcase.capitalize
163
- }.to_json,
164
- @headers
165
- )
166
- end
167
-
168
- if resp.code.to_i == 200
169
- @logger.error("User permissions have been updated: #{resp.body}") if @debug
170
- return true
171
- else
172
- @logger.error("Could not update user permissions (HTTP #{resp.code}: #{resp.body})") if @debug
173
- return false
174
- end
175
- rescue => e
176
- @logger.error("Could not update user permissions: #{e}") if @debug
177
- return false
178
- end
179
- end
180
-
181
- def delete_user(id)
182
- if id == 1
183
- @logger.warn("Can't delete user ID #{id} (admin user)") if @debug
184
- return false
185
- end
186
- @logger.info("Deleting user ID #{id} (DELETE /api/admin/users/#{id})") if @debug
187
- begin
188
- resp = @api_instance["/api/admin/users/#{id}"].delete(@headers)
189
- if resp.code.to_i == 200
190
- @logger.info("User ID #{id} has been deleted") if @debug
191
- return true
192
- else
193
- @logger.error("Could note delete: #{resp.body}") if @debug
194
- return false
195
- end
196
- rescue => e
197
- @logger.error("Could not delete user: #{e}") if @debug
198
- return false
199
- end
200
- end
201
-
202
-
203
-
204
- def get_data_sources()
205
- begin
206
- @logger.info("Attempting to get existing data sources (GET /api/datasources)") if @debug
207
- resp = @api_instance['/api/datasources'].get(@headers)
208
- data_sources = JSON.parse(resp.body)
209
- data_source_map = {}
210
- data_sources.each { |ds|
211
- data_source_map[ds['id']] = ds
212
- }
213
- if resp.code.to_i == 200
214
- return data_source_map
215
- else
216
- @logger.error("Could not retreive data sources (HTTP #{resp.code}: #{resp.body})") if @debug
217
- return false
218
- end
219
- rescue => e
220
- @logger.error("Error getting existing data sources: #{e}") if @debug
221
- return false
222
- end
223
- end
224
-
225
- def get_data_source(id)
226
- begin
227
- @logger.info("Attempting to get existing data source ID #{id}") if @debug
228
- resp = @api_instance["/api/datasources/#{id}"].get(@headers)
229
- if resp.code.to_i == 200
230
- return JSON.parse(resp.body)
231
- else
232
- @logger.error("Could not get data source (HTTP #{resp.code}: #{resp.body})") if @debug
233
- return false
234
- end
235
- rescue => e
236
- @logger.error("Error getting existing data sources: #{e}") if @debug
237
- return false
238
- end
239
- end
240
-
241
- def update_data_source(id, ds={})
242
- @logger.info("Updating data source ID #{id}") if @debug
243
-
244
- existing_ds = self.get_data_source(id)
245
- ds = existing_ds.merge(ds)
246
- @logger.info(ds)
247
-
248
- begin
249
- resp = @api_instance["/api/datasources/#{id}"].put(
250
- ds.to_json,
251
- @headers
252
- )
253
- if resp.code.to_i == 200
254
- @logger.info("Data source successfully updated") if @debug
255
- return true
256
- else
257
- @logger.info("Data source could not be updated (HTTP #{resp.code}: #{resp.body})") if @debug
258
- return false
259
- end
260
- rescue => e
261
- @logger.error("Error updating data source: #{e}") if @debug
262
- return false
263
- end
264
- end
265
-
266
- def create_data_source(ds={})
267
- @logger.info("Creating data source: #{ds['name']} (database: #{ds['database']})") if @debug
268
- begin
269
- resp = @api_instance["/api/datasources"].post(
270
- ds.to_json,
271
- @headers
272
- )
273
- result = JSON.parse(resp.body)
274
- if resp.code.to_i == 200
275
- @logger.info("Data source ID #{result['id']} has been created") if @debug
276
- return true
277
- else
278
- @logger.error("Data source could not be created (HTTP #{resp.code}: #{resp.body})") if @debug
279
- return false
280
- end
281
- rescue => e
282
- @logger.error("Error creating data source: #{e}") if @debug
283
- return false
284
- end
285
- end
286
-
287
- def delete_data_source(id)
288
- @logger.info("Deleting data source #{id}") if @debug
289
- begin
290
- resp = @api_instance["/api/datasources/#{id}"].delete(@headers)
291
- result = JSON.parse(resp.body)
292
- if resp.code.to_i == 200
293
- @logger.info("Data source ID #{id} has been deleted") if @debug
294
- return true
295
- else
296
- @logger.error("Data source could not be deleted (HTTP #{resp.code}): #{resp.body}") if @debug
297
- return false
298
- end
299
- rescue => e
300
- @logger.error("Error creating data source: #{e}") if @debug
301
- return false
302
- end
303
- end
304
-
305
-
306
-
307
- def get_current_org()
308
- @logger.info("Getting current organization (GET /api/org)") if @debug
309
- begin
310
- resp = @api_instance['/api/org'].get(@headers)
311
- if resp.code.to_i == 200
312
- return JSON.parse(resp.body)
313
- else
314
- @logger.error("Could not get current organization: #{resp.body}") if @debug
315
- return false
316
- end
317
- rescue => e
318
- @logger.error("Could not get current organization: #{e}") if @debug
319
- return false
320
- end
321
- end
322
-
323
- def ping_session()
324
- @logger.info("Pingning current session (GET /api/login/ping)") if @debug
325
- begin
326
- resp = @api_instance['/api/login/ping'].get(@headers)
327
- if resp.code.to_i == 200
328
- return true
329
- else
330
- @logger.error("Could not ping session: #{resp.body}") if @debug
331
- return false
332
- end
333
- rescue => e
334
- @logger.error("Could not ping session: #{e}") if @debug
335
- return false
336
- end
337
- end
338
-
339
- def get_admin_settings()
340
- @logger.info("Getting admin settings (GET /api/admin/settings)") if @debug
341
- begin
342
- resp = @api_instance['/api/admin/settings'].get(@headers)
343
- if resp.code.to_i == 200
344
- return JSON.parse(resp.body)
345
- else
346
- @logger.error("Could not get admin settings: #{resp.body}") if @debug
347
- return false
348
- end
349
- rescue => e
350
- @logger.error("Could not get admin settings: #{e}") if @debug
351
- return false
352
- end
353
- end
354
-
355
- end