grafana 0.8.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +8 -3
  3. data/lib/grafana/admin.rb +39 -65
  4. data/lib/grafana/alerts.rb +334 -14
  5. data/lib/grafana/annotations.rb +284 -9
  6. data/lib/grafana/client.rb +38 -1
  7. data/lib/grafana/dashboard.rb +182 -39
  8. data/lib/grafana/dashboard_permissions.rb +132 -0
  9. data/lib/grafana/dashboard_versions.rb +101 -5
  10. data/lib/grafana/datasource.rb +93 -49
  11. data/lib/grafana/folder.rb +198 -0
  12. data/lib/grafana/folder_and_dashboard_search.rb +57 -0
  13. data/lib/grafana/folder_permissions.rb +155 -0
  14. data/lib/grafana/login.rb +41 -35
  15. data/lib/grafana/network.rb +128 -91
  16. data/lib/grafana/organization.rb +65 -34
  17. data/lib/grafana/organizations.rb +119 -175
  18. data/lib/grafana/playlist.rb +599 -0
  19. data/lib/grafana/preferences.rb +122 -0
  20. data/lib/grafana/tags.rb +19 -8
  21. data/lib/grafana/teams.rb +364 -0
  22. data/lib/grafana/tools.rb +44 -12
  23. data/lib/grafana/user.rb +78 -39
  24. data/lib/grafana/users.rb +104 -53
  25. data/lib/grafana/validator.rb +47 -2
  26. data/lib/grafana/version.rb +3 -3
  27. metadata +13 -38
  28. data/doc/Array.html +0 -200
  29. data/doc/Boolean.html +0 -122
  30. data/doc/FalseClass.html +0 -132
  31. data/doc/Grafana.html +0 -172
  32. data/doc/Hash.html +0 -212
  33. data/doc/Logging.html +0 -326
  34. data/doc/Object.html +0 -286
  35. data/doc/Time.html +0 -200
  36. data/doc/TrueClass.html +0 -132
  37. data/doc/_index.html +0 -380
  38. data/doc/class_list.html +0 -51
  39. data/doc/file.README.html +0 -117
  40. data/doc/file_list.html +0 -56
  41. data/doc/frames.html +0 -17
  42. data/doc/index.html +0 -117
  43. data/doc/method_list.html +0 -771
  44. data/doc/top-level-namespace.html +0 -112
@@ -0,0 +1,599 @@
1
+
2
+ module Grafana
3
+
4
+ # +++
5
+ # title = "Playlist HTTP API "
6
+ # description = "Playlist Admin HTTP API"
7
+ # keywords = ["grafana", "http", "documentation", "api", "playlist"]
8
+ # aliases = ["/http_api/playlist/"]
9
+ # type = "docs"
10
+ # [menu.docs]
11
+ # name = "Playlist"
12
+ # parent = "http_api"
13
+ # +++
14
+
15
+ # https://github.com/grafana/grafana/blob/1165d098b0d0ae705955f9d2ea104beea98ca6eb/pkg/api/dtos/playlist.go
16
+
17
+ module Playlist
18
+
19
+ ## Playlist API
20
+ #
21
+ ### Search Playlist
22
+ #
23
+ #`GET /api/playlists`
24
+ #
25
+ #Get all existing playlist for the current organization using pagination
26
+ #
27
+ #**Example Request**:
28
+ #
29
+ #```bash
30
+ #GET /api/playlists HTTP/1.1
31
+ #Accept: application/json
32
+ #Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
33
+ #```
34
+ #
35
+ # Querystring Parameters:
36
+ #
37
+ # These parameters are used as querystring parameters.
38
+ #
39
+ # - **query** - Limit response to playlist having a name like this value.
40
+ # - **limit** - Limit response to *X* number of playlist.
41
+ #
42
+ #**Example Response**:
43
+ #
44
+ #```json
45
+ #HTTP/1.1 200
46
+ #Content-Type: application/json
47
+ #[
48
+ # {
49
+ # "id": 1,
50
+ # "name": "my playlist",
51
+ # "interval": "5m"
52
+ # }
53
+ #]
54
+ #```
55
+ def playlists
56
+
57
+ endpoint = '/api/playlists'
58
+
59
+ @logger.debug("Attempting to get all existing playlists (GET #{endpoint})") if @debug
60
+
61
+ playlists = get( endpoint )
62
+
63
+ return { 'status' => 404, 'message' => 'No Playlists found' } if( playlists.nil? || playlists == false || playlists.dig('status').to_i != 200 )
64
+
65
+ playlists
66
+ end
67
+
68
+ ### Get one playlist
69
+ #
70
+ #`GET /api/playlists/:id`
71
+ #
72
+ #**Example Request**:
73
+ #
74
+ #```bash
75
+ #GET /api/playlists/1 HTTP/1.1
76
+ #Accept: application/json
77
+ #Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
78
+ #```
79
+ #
80
+ #**Example Response**:
81
+ #
82
+ #```json
83
+ #HTTP/1.1 200
84
+ #Content-Type: application/json
85
+ #{
86
+ # "id" : 1,
87
+ # "name": "my playlist",
88
+ # "interval": "5m",
89
+ # "orgId": "my org",
90
+ # "items": [
91
+ # {
92
+ # "id": 1,
93
+ # "playlistId": 1,
94
+ # "type": "dashboard_by_id",
95
+ # "value": "3",
96
+ # "order": 1,
97
+ # "title":"my third dasboard"
98
+ # },
99
+ # {
100
+ # "id": 2,
101
+ # "playlistId": 1,
102
+ # "type": "dashboard_by_tag",
103
+ # "value": "myTag",
104
+ # "order": 2,
105
+ # "title":"my other dasboard"
106
+ # }
107
+ # ]
108
+ #}
109
+ #```
110
+
111
+ def playlist( playlist_id )
112
+
113
+ if( playlist_id.is_a?(String) && playlist_id.is_a?(Integer) )
114
+ raise ArgumentError.new(format('wrong type. \'playlist_id\' must be an String (for an Playlist name) or an Integer (for an Playlist Id), given \'%s\'', playlist_id.class.to_s))
115
+ end
116
+ raise ArgumentError.new('missing \'playlist_id\'') if( playlist_id.size.zero? )
117
+
118
+ if(playlist_id.is_a?(String))
119
+
120
+ data = playlists
121
+ status = data.dig('status')
122
+ d = data.dig('message')
123
+ data = d.select { |k| k['name'] == playlist_id }
124
+
125
+ return { 'status' => 404, 'message' => format( 'No Playlist \'%s\' found', playlist_id) } if( data.size == 0 )
126
+
127
+ if( data.size != 0 )
128
+
129
+ _d = []
130
+ data.each do |k,v|
131
+ _d << playlist( k['id'] )
132
+ end
133
+ return { 'status' => status, 'playlists' => _d }
134
+ end
135
+ # return { 'status' => 200, 'message' => data } if( data.size != 0 )
136
+ end
137
+
138
+ raise format('playlist id can not be 0') if( playlist_id.zero? )
139
+
140
+ endpoint = format('/api/playlists/%d', playlist_id )
141
+
142
+ @logger.debug("Attempting to get existing playlist id #{playlist_id} (GET #{endpoint})") if @debug
143
+
144
+ result = get(endpoint)
145
+
146
+ return { 'status' => 404, 'message' => 'playlist is empty', 'items' => [] } if( result.dig('status') == 404 )
147
+
148
+ return result
149
+ end
150
+
151
+ ### Get Playlist items
152
+
153
+ #`GET /api/playlists/:id/items`
154
+ #
155
+ #**Example Request**:
156
+ #
157
+ #```bash
158
+ #GET /api/playlists/1/items HTTP/1.1
159
+ #Accept: application/json
160
+ #Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
161
+ #```
162
+ #
163
+ #**Example Response**:
164
+ #
165
+ #```json
166
+ #HTTP/1.1 200
167
+ #Content-Type: application/json
168
+ #[
169
+ # {
170
+ # "id": 1,
171
+ # "playlistId": 1,
172
+ # "type": "dashboard_by_id",
173
+ # "value": "3",
174
+ # "order": 1,
175
+ # "title":"my third dasboard"
176
+ # },
177
+ # {
178
+ # "id": 2,
179
+ # "playlistId": 1,
180
+ # "type": "dashboard_by_tag",
181
+ # "value": "myTag",
182
+ # "order": 2,
183
+ # "title":"my other dasboard"
184
+ # }
185
+ #]
186
+ #```
187
+
188
+ def playlist_items( playlist_id, multi_result = false )
189
+
190
+ if( playlist_id.is_a?(String) && playlist_id.is_a?(Integer) )
191
+ raise ArgumentError.new(format('wrong type. \'playlist_id\' must be an String (for an playlist name) or an Integer (for an playlist Id), given \'%s\'', playlist_id.class.to_s))
192
+ end
193
+ raise ArgumentError.new('missing \'playlist_id\'') if( playlist_id.size.zero? )
194
+
195
+ _playlists = playlists
196
+
197
+ begin
198
+ status = _playlists.dig('status')
199
+ message = _playlists.dig('message')
200
+
201
+ if( status == 200 )
202
+
203
+ data = message.select { |k| k['id'] == playlist_id } if( playlist_id.is_a?(Integer) )
204
+ data = message.select { |k| k['name'] == playlist_id } if( playlist_id.is_a?(String) )
205
+
206
+ return { 'status' => 404, 'message' => 'No Playlist found' } if( !data.is_a?(Array) || data.count == 0 || status.to_i != 200 )
207
+ return { 'status' => 404, 'message' => format('found %d playlists with name %s', data.count, playlist_id ) } if( data.count > 1 && multi_result == false )
208
+
209
+ id = data.first.dig('id')
210
+ else
211
+ return _playlists
212
+ end
213
+ rescue
214
+ return { 'status' => 404, 'message' => 'No Playlists found' } if( playlists.nil? || playlists == false || playlists.dig('status').to_i != 200 )
215
+ end
216
+
217
+ endpoint = "/api/playlists/#{id}/items"
218
+
219
+ result = get( endpoint )
220
+
221
+ return { 'status' => 404, 'message' => 'playlist is empty' } if( result.dig('status') == 404 )
222
+
223
+ return result
224
+ end
225
+
226
+ ### Get Playlist dashboards
227
+ #
228
+ #`GET /api/playlists/:id/dashboards`
229
+ #
230
+ #**Example Request**:
231
+ #
232
+ #```bash
233
+ #GET /api/playlists/1/dashboards HTTP/1.1
234
+ #Accept: application/json
235
+ #Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
236
+ #```
237
+ #
238
+ #**Example Response**:
239
+ #
240
+ #```json
241
+ #HTTP/1.1 200
242
+ #Content-Type: application/json
243
+ #[
244
+ # {
245
+ # "id": 3,
246
+ # "title": "my third dasboard",
247
+ # "order": 1,
248
+ # },
249
+ # {
250
+ # "id": 5,
251
+ # "title":"my other dasboard"
252
+ # "order": 2,
253
+ #
254
+ # }
255
+ #]
256
+ #```
257
+
258
+ def playlist_dashboards( playlist_id )
259
+
260
+ raise ArgumentError.new(format('wrong type. \'playlist_id\' must be an Integer, given \'%s\'', playlist_id.class)) unless( playlist_id.is_a?(Integer) )
261
+ raise ArgumentError.new('missing \'playlist_id\'') if( playlist_id.size.zero? )
262
+
263
+ endpoint = format('/api/playlists/%s/dashboards', playlist_id)
264
+
265
+ @logger.debug( "Attempting to get playlist (GET #{endpoint})" ) if @debug
266
+ get(endpoint)
267
+ end
268
+
269
+ # Create a playlist
270
+
271
+ # `POST /api/playlists/`
272
+ #
273
+ #**Example Request**:
274
+ #
275
+ #```bash
276
+ #PUT /api/playlists/1 HTTP/1.1
277
+ #Accept: application/json
278
+ #Content-Type: application/json
279
+ #Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
280
+ # {
281
+ # "name": "my playlist",
282
+ # "interval": "5m",
283
+ # "items": [
284
+ # {
285
+ # "type": "dashboard_by_id",
286
+ # "value": "3",
287
+ # "order": 1,
288
+ # "title":"my third dasboard"
289
+ # },
290
+ # {
291
+ # "type": "dashboard_by_tag",
292
+ # "value": "myTag",
293
+ # "order": 2,
294
+ # "title":"my other dasboard"
295
+ # }
296
+ # ]
297
+ # }
298
+ #```
299
+ #
300
+ #**Example Response**:
301
+ #
302
+ #```json
303
+ #HTTP/1.1 200
304
+ #Content-Type: application/json
305
+ # {
306
+ # "id": 1,
307
+ # "name": "my playlist",
308
+ # "interval": "5m"
309
+ # }
310
+ #```
311
+
312
+ def create_playlist( params )
313
+
314
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
315
+ raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
316
+
317
+ # v, mv = version.values
318
+ # return { 'status' => 404, 'message' => format( 'folder has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
319
+
320
+ name = validate( params, required: true , var: 'name' , type: String )
321
+ interval = validate( params, required: true , var: 'interval' , type: String )
322
+ items = validate( params, required: true , var: 'items' , type: Array )
323
+
324
+ return { 'status' => 404, 'message' => 'There are no elements for a playlist' } if(items.count == 0)
325
+
326
+ payload_items = create_playlist_items(items)
327
+
328
+ payload = {
329
+ name: name,
330
+ interval: interval,
331
+ items: payload_items
332
+ }
333
+ payload.reject!{ |_k, v| v.nil? }
334
+
335
+ endpoint = '/api/playlists'
336
+
337
+ post(endpoint, payload.to_json)
338
+ end
339
+
340
+ ### Update a playlist
341
+ #
342
+ #`PUT /api/playlists/:id`
343
+ #
344
+ #**Example Request**:
345
+ #
346
+ #```bash
347
+ #PUT /api/playlists/1 HTTP/1.1
348
+ #Accept: application/json
349
+ #Content-Type: application/json
350
+ #Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
351
+ # {
352
+ # "name": "my playlist",
353
+ # "interval": "5m",
354
+ # "items": [
355
+ # {
356
+ # "playlistId": 1,
357
+ # "type": "dashboard_by_id",
358
+ # "value": "3",
359
+ # "order": 1,
360
+ # "title":"my third dasboard"
361
+ # },
362
+ # {
363
+ # "playlistId": 1,
364
+ # "type": "dashboard_by_tag",
365
+ # "value": "myTag",
366
+ # "order": 2,
367
+ # "title":"my other dasboard"
368
+ # }
369
+ # ]
370
+ # }
371
+ #```
372
+ #
373
+ #**Example Response**:
374
+ #
375
+ #```json
376
+ #HTTP/1.1 200
377
+ #Content-Type: application/json
378
+ #{
379
+ # "id" : 1,
380
+ # "name": "my playlist",
381
+ # "interval": "5m",
382
+ # "orgId": "my org",
383
+ # "items": [
384
+ # {
385
+ # "id": 1,
386
+ # "playlistId": 1,
387
+ # "type": "dashboard_by_id",
388
+ # "value": "3",
389
+ # "order": 1,
390
+ # "title":"my third dasboard"
391
+ # },
392
+ # {
393
+ # "id": 2,
394
+ # "playlistId": 1,
395
+ # "type": "dashboard_by_tag",
396
+ # "value": "myTag",
397
+ # "order": 2,
398
+ # "title":"my other dasboard"
399
+ # }
400
+ # ]
401
+ #}
402
+ #```
403
+
404
+ def update_playlist( params )
405
+
406
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
407
+ raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
408
+
409
+ playlist_id = validate( params, required: true , var: 'playlist' )
410
+ name = validate( params, required: false, var: 'name' )
411
+ interval = validate( params, required: false, var: 'interval', type: String )
412
+ # organisation = validate( params, required: false, var: 'organisation' )
413
+ items = validate( params, required: false, var: 'items', type: Array )
414
+
415
+ _playlists = playlists
416
+
417
+ data = []
418
+
419
+ begin
420
+ status = _playlists.dig('status')
421
+ message = _playlists.dig('message')
422
+
423
+ if( status == 200 )
424
+ data = message.select { |k| k['id'] == playlist_id } if( playlist_id.is_a?(Integer) )
425
+ data = message.select { |k| k['name'] == playlist_id } if( playlist_id.is_a?(String) )
426
+
427
+ return { 'status' => 404, 'message' => 'no playlist found' } if( !data.is_a?(Array) || data.count == 0 || status.to_i != 200 )
428
+ return { 'status' => 404, 'message' => format('found %d playlists with name %s', data.count, playlist_id ) } if( data.count > 1 && multi_result == false )
429
+ else
430
+ return _playlists
431
+ end
432
+ rescue
433
+ return { 'status' => 404, 'message' => 'no playlists found' } if( playlists.nil? || playlists == false || playlists.dig('status').to_i != 200 )
434
+ end
435
+
436
+ playlist_id = data.first.dig('id')
437
+ playlist_name = data.first.dig('name')
438
+ payload_items = create_playlist_items(items, playlist_id)
439
+
440
+ payload = {
441
+ id: playlist_id,
442
+ name: name,
443
+ interval: interval,
444
+ items: payload_items
445
+ }
446
+ payload.reject!{ |_k, v| v.nil? }
447
+
448
+ endpoint = format( '/api/playlists/%d', playlist_id )
449
+
450
+ put( endpoint, payload.to_json )
451
+
452
+ end
453
+
454
+
455
+ ### Delete a playlist
456
+ #
457
+ #`DELETE /api/playlists/:id`
458
+ #
459
+ #**Example Request**:
460
+ #
461
+ #```bash
462
+ #DELETE /api/playlists/1 HTTP/1.1
463
+ #Accept: application/json
464
+ #Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
465
+ #```
466
+ #
467
+ #**Example Response**:
468
+ #
469
+ #```json
470
+ #HTTP/1.1 200
471
+ #Content-Type: application/json
472
+ #{}
473
+ #```
474
+
475
+ def delete_playlist(playlist_id, multi_result = false )
476
+
477
+ if( playlist_id.is_a?(String) && playlist_id.is_a?(Integer) )
478
+ raise ArgumentError.new(format('wrong type. \'playlist_id\' must be an String (for an Playlist name) or an Integer (for an Playlist Id), given \'%s\'', playlist_id.class.to_s))
479
+ end
480
+ raise ArgumentError.new('missing \'playlist_id\'') if( playlist_id.size.zero? )
481
+
482
+ _playlists = playlists
483
+
484
+ data = []
485
+
486
+ begin
487
+ status = _playlists.dig('status')
488
+ message = _playlists.dig('message')
489
+
490
+ if( status == 200 )
491
+
492
+ data = message.select { |k| k['id'] == playlist_id } if( playlist_id.is_a?(Integer) )
493
+ data = message.select { |k| k['name'] == playlist_id } if( playlist_id.is_a?(String) )
494
+
495
+ return { 'status' => 404, 'message' => 'no playlist found' } if( !data.is_a?(Array) || data.count == 0 || status.to_i != 200 )
496
+ return { 'status' => 404, 'message' => format('found %d playlists with name %s', data.count, playlist_id ) } if( data.count > 1 && multi_result == false )
497
+ else
498
+ return _playlists
499
+ end
500
+ rescue
501
+ return { 'status' => 404, 'message' => 'no playlists found' } if( playlists.nil? || playlists == false || playlists.dig('status').to_i != 200 )
502
+ end
503
+
504
+ if( multi_result == true )
505
+
506
+ result = { 'status' => 0, 'message' => 'under development' }
507
+ data.each do |x|
508
+
509
+ endpoint = format( '/api/playlists/%d', x.dig('id') )
510
+
511
+ begin
512
+ result = delete( endpoint )
513
+ rescue => error
514
+ logger.error( "error: #{error}" )
515
+ end
516
+ end
517
+
518
+ return result
519
+ else
520
+
521
+ playlist_id = data.first.dig('id')
522
+
523
+ endpoint = format( '/api/playlists/%d', playlist_id )
524
+
525
+ result = delete( endpoint )
526
+
527
+ if(result.dig('status').to_i == 500)
528
+ # check if the playlist exists
529
+ r = playlist( playlist_id )
530
+ return { 'status' => 200, 'message' => 'playlist deleted' } if(r.dig('status').to_i == 404)
531
+ end
532
+
533
+ return result
534
+ end
535
+
536
+ end
537
+
538
+
539
+ private
540
+ def create_playlist_items( items, playlistId = nil)
541
+
542
+ _items = []
543
+
544
+ items.each do |r|
545
+ _element = {}
546
+
547
+ if( r['name'] )
548
+
549
+ _name = search_dashboards( query: r['name'] )
550
+ _name_status = _name.dig('status')
551
+
552
+ next unless( _name_status == 200 )
553
+
554
+ _name = _name.dig('message')
555
+ _name_id = _name.first.dig('id')
556
+ _name_title = _name.first.dig('title')
557
+
558
+ _element[:type] = 'dashboard_by_id'
559
+ _element[:value] = _name_id.to_s
560
+ _element[:title] = _name_title
561
+ _element[:playlistId] = playlistId unless(playlistId.nil?)
562
+
563
+ elsif( r['id'] )
564
+
565
+ _uid = dashboard_by_uid(r['id'])
566
+ _uid_status = _uid.dig('status')
567
+
568
+ next unless( _uid_status == 200 )
569
+
570
+ _element[:type] = 'dashboard_by_id'
571
+ _element[:value] = r['id']
572
+ _element[:playlistId] = playlistId unless(playlistId.nil?)
573
+
574
+ elsif( r['tag'] )
575
+
576
+ _tags = search_dashboards( tags: r['tag'] )
577
+ _tags_status = _tags.dig('status')
578
+
579
+ next unless( _tags_status == 200 )
580
+
581
+ _element[:type] = 'dashboard_by_tag'
582
+ _element[:value] = r['tag']
583
+ _element[:title] = r['tag']
584
+ _element[:playlistId] = playlistId unless(playlistId.nil?)
585
+
586
+ else
587
+ next
588
+ end
589
+
590
+ _element[:order] = r['order'] if(r['order'])
591
+
592
+ _items << _element if(_element.count >= 4)
593
+ end
594
+
595
+ _items
596
+ end
597
+
598
+ end
599
+ end