grafana-api 0.0.1
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 +7 -0
- data/lib/grafana-api.rb +355 -0
- metadata +72 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: a8db882d27b2ce8806d6eb17c2476610847d3415
|
|
4
|
+
data.tar.gz: 2a793a77bb449405582ae6b2a6cf44ea80986a1e
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 5485c5c075a442b7bbddbdeb3b4a4bd4c611c869136294d237c2d03c2efdf6d40e569121ff255509f4249fffee52ca254779be26bd2cc5ed1216ef3a49c4de91
|
|
7
|
+
data.tar.gz: 633e33e84f22a60bef80c52640887b89b57d26e9aeefaa7c74ada8166e4b12653dae793607c93db218fc6ffdb71ac7b80fbe1f4457b523da3c237cecf2e5d6e6
|
data/lib/grafana-api.rb
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
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
|
metadata
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: grafana-api
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Alain Lefebvre
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2015-11-13 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: json
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ~>
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.7'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ~>
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.7'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rest-client
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ~>
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '1.8'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ~>
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '1.8'
|
|
41
|
+
description: A simple wrapper for the Grafana HTTP API
|
|
42
|
+
email: devtools@lightspeedpos.com
|
|
43
|
+
executables: []
|
|
44
|
+
extensions: []
|
|
45
|
+
extra_rdoc_files: []
|
|
46
|
+
files:
|
|
47
|
+
- lib/grafana-api.rb
|
|
48
|
+
homepage: http://github.com/lightspeedretail/ruby-grafana-api
|
|
49
|
+
licenses:
|
|
50
|
+
- MIT
|
|
51
|
+
metadata: {}
|
|
52
|
+
post_install_message:
|
|
53
|
+
rdoc_options: []
|
|
54
|
+
require_paths:
|
|
55
|
+
- lib
|
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - '>='
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - '>='
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '0'
|
|
66
|
+
requirements: []
|
|
67
|
+
rubyforge_project:
|
|
68
|
+
rubygems_version: 2.0.14
|
|
69
|
+
signing_key:
|
|
70
|
+
specification_version: 4
|
|
71
|
+
summary: Grafana API Wrapper
|
|
72
|
+
test_files: []
|