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
@@ -1,39 +1,314 @@
1
1
 
2
2
  module Grafana
3
3
 
4
- # http://docs.grafana.org/http_api/annotations/
4
+ # This is the API documentation for the new Grafana Annotations feature released in Grafana 4.6.
5
+ # Annotations are saved in the Grafana database (sqlite, mysql or postgres).
6
+ #
7
+ # Annotations can be global annotations that can be shown on any dashboard by configuring an annotation
8
+ # data source - they are filtered by tags.
9
+ #
10
+ # Or they can be tied to a panel on a dashboard and are then only shown on that panel.
11
+ #
12
+ # original API Documentation can be found under: http://docs.grafana.org/http_api/annotations/
5
13
  #
6
14
  module Annotations
7
15
 
8
16
  # Find Annotations
9
17
  # http://docs.grafana.org/http_api/annotations/#find-annotations
10
- # GET /api/annotations?from=1506676478816&to=1507281278816&tags=tag1&tags=tag2&limit=100
11
- def find_annotation( params ); end
18
+ #
19
+ # @param [Hash] params
20
+ # @option params [Integer] from: epoch datetime in milliseconds. Optional.
21
+ # @option params [Integer] to: epoch datetime in milliseconds. Optional.
22
+ # @option params [Integer] limit: number. Optional - default is 10. Max limit for results returned.
23
+ # @option params [Integer] alert_id: number. Optional. Find annotations for a specified alert.
24
+ # @option params [Mixed] dashboard: number. Optional. Find annotations that are scoped to a specific dashboard
25
+ # @option params [Integer] panel_id: number. Optional. Find annotations that are scoped to a specific panel
26
+ # @option params [Array] tags: Optional. Use this to filter global annotations.
27
+ # Global annotations are annotations from an annotation data source that are not connected specifically to a dashboard or panel.
28
+ # To do an "AND" filtering with multiple tags, specify the tags parameter multiple times e.g.
29
+ #
30
+ # @example
31
+ # params = {
32
+ # limit: 5,
33
+ # tags: [ 'spec', 'test' ]
34
+ # }
35
+ # find_annotation( params )
36
+ #
37
+ # @return [Array]
38
+ #
39
+ def find_annotation( params )
40
+
41
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
42
+ raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
43
+
44
+ dashboard = validate( params, required: false, var: 'dashboard' )
45
+ from = validate( params, required: false, var: 'from', type: Integer )
46
+ to = validate( params, required: false, var: 'to', type: Integer )
47
+ limit = validate( params, required: false, var: 'limit', type: Integer ) || 10
48
+ alert_id = validate( params, required: false, var: 'alert_id', type: Integer )
49
+ panel_id = validate( params, required: false, var: 'panel_id', type: Integer )
50
+ tags = validate( params, required: false, var: 'tags', type: Array )
51
+
52
+ if( dashboard.is_a?(String) )
53
+
54
+ dashboard = search_dashboards( query: dashboard )
55
+
56
+ return { 'status' => 404, 'message' => format( 'No Dashboard \'%s\' found', dashboard) } if( dashboard.nil? || dashboard.dig('status').to_i != 200 )
57
+
58
+ dashboard = dashboard.dig('message').first unless( dashboard.nil? && dashboard.dig('status').to_i == 200 )
59
+ dashboard = dashboard.dig('id') unless( dashboard.nil? )
60
+
61
+ return { 'status' => 404, 'message' => format( 'No Dashboard \'%s\' found', dashboard) } if( dashboard.nil? )
62
+ end
63
+
64
+ api = []
65
+ api << format( 'from=%s', from ) unless( from.nil? )
66
+ api << format( 'to=%s', to ) unless( to.nil? )
67
+ api << format( 'limit=%s', limit ) unless( limit.nil? )
68
+ api << format( 'alertId=%s', alert_id ) unless( alert_id.nil? )
69
+ api << format( 'panelId=%s', panel_id ) unless( panel_id.nil? )
70
+ api << format( 'dashboardId=%s', dashboard ) unless( dashboard.nil? )
71
+
72
+ unless( tags.nil? )
73
+ tags = tags.join( '&tags=' ) if( tags.is_a?( Array ) )
74
+ api << format( 'tags=%s', tags )
75
+ end
76
+ api = api.join( '&' )
77
+
78
+ endpoint = format( '/api/annotations/?%s' , api )
79
+
80
+ @logger.debug("Attempting to search for annotations (GET #{endpoint})") if @debug
81
+
82
+ get( endpoint )
83
+ end
12
84
 
13
85
  # Create Annotation
86
+ #
87
+ # Creates an annotation in the Grafana database.
88
+ # The dashboard_id and panel_id fields are optional.
89
+ # If they are not specified then a global annotation is created and can be queried in any dashboard that adds
90
+ # the Grafana annotations data source.
91
+ #
92
+ # When creating a region annotation the response will include both id and endId, if not only id.
93
+ #
14
94
  # http://docs.grafana.org/http_api/annotations/#create-annotation
15
95
  # POST /api/annotations
16
- def create_annotation( params ); end
96
+ #
97
+ #
98
+ # @param [Hash] params
99
+ # @option params [Mixed] dashboard
100
+ # @option params [Integer] panel_id
101
+ # @option params [Integer] time:
102
+ # @option params [Integer] time_end:
103
+ # @option params [Boolean] region:
104
+ # @option params [Array] tags:
105
+ # @option params [String] text:
106
+ #
107
+ # @example
108
+ # params = {
109
+ # time: Time.now.to_i,
110
+ # tags: [ 'spec', 'test' ],
111
+ # text: 'test annotation'
112
+ # }
113
+ # create_annotation( params )
114
+ #
115
+ # @return [Hash]
116
+ #
117
+ def create_annotation( params )
118
+
119
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
120
+ raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
121
+
122
+ dashboard = validate( params, required: false, var: 'dashboard' )
123
+ panel_id = validate( params, required: false, var: 'panel_id', type: Integer )
124
+ time = validate( params, required: false, var: 'time', type: Integer ) || Time.now.to_i
125
+ time_end = validate( params, required: false, var: 'time_end', type: Integer )
126
+ region = validate( params, required: false, var: 'region', type: Boolean )
127
+ tags = validate( params, required: true, var: 'tags', type: Array )
128
+ text = validate( params, required: true, var: 'text', type: String )
129
+
130
+ if( dashboard.is_a?(String) )
131
+
132
+ dashboard = search_dashboards( query: dashboard )
133
+
134
+ return { 'status' => 404, 'message' => format( 'No Dashboard \'%s\' found', dashboard) } if( dashboard.nil? || dashboard.dig('status').to_i != 200 )
135
+
136
+ dashboard = dashboard.dig('message').first unless( dashboard.nil? && dashboard.dig('status').to_i == 200 )
137
+ dashboard = dashboard.dig('id') unless( dashboard.nil? )
138
+
139
+ return { 'status' => 404, 'message' => format( 'No Dashboard \'%s\' found', dashboard) } if( dashboard.nil? )
140
+ end
141
+
142
+ unless( time_end.nil? )
143
+ return { 'status' => 404, 'message' => format( '\'end_time\' can\'t be lower then \'time\'' ) } if( time_end < time )
144
+ end
145
+
146
+ endpoint = '/api/annotations'
147
+ payload = {
148
+ dashboardId: dashboard,
149
+ panelId: panel_id,
150
+ time: time,
151
+ timeEnd: time_end,
152
+ isRegion: region,
153
+ tags: tags,
154
+ text: text
155
+ }
156
+ payload.reject!{ |_k, v| v.nil? }
157
+
158
+ post(endpoint, payload.to_json)
159
+ end
17
160
 
18
161
  # Create Annotation in Graphite format
162
+ #
163
+ # Creates an annotation by using Graphite-compatible event format.
164
+ # The when and data fields are optional.
165
+ # If when is not specified then the current time will be used as annotation's timestamp.
166
+ # The tags field can also be in prior to Graphite 0.10.0 format (string with multiple tags being separated by a space).
167
+ #
19
168
  # http://docs.grafana.org/http_api/annotations/#create-annotation-in-graphite-format
20
169
  # POST /api/annotations/graphite
21
- def create_annotation_graphite( params ); end
170
+ #
171
+ # @param [Hash] params
172
+ # @option params [Integer] what
173
+ # @option params [Integer] when
174
+ # @option params [Array] tags
175
+ # @option params [String] data
176
+ #
177
+ # @example
178
+ # params = {
179
+ # what: 'spec test graphite annotation',
180
+ # when: Time.now.to_i,
181
+ # tags: [ 'spec', 'test' ],
182
+ # data: 'test annotation'
183
+ # }
184
+ # create_annotation_graphite( params )
185
+ #
186
+ # @return [Hash]
187
+ #
188
+ def create_annotation_graphite( params )
189
+
190
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
191
+ raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
192
+
193
+ what = validate( params, required: true , var: 'what', type: String )
194
+ time_when = validate( params, required: false, var: 'when', type: Integer ) || Time.now.to_i
195
+ tags = validate( params, required: true , var: 'tags', type: Array )
196
+ data = validate( params, required: false, var: 'data', type: String )
197
+
198
+ endpoint = '/api/annotations/graphite'
199
+ payload = {
200
+ what: what,
201
+ when: time_when,
202
+ tags: tags,
203
+ data: data
204
+ }
205
+ payload.reject!{ |_k, v| v.nil? }
206
+
207
+ post(endpoint, payload.to_json)
208
+ end
22
209
 
23
210
  # Update Annotation
211
+ #
24
212
  # http://docs.grafana.org/http_api/annotations/#update-annotation
25
- # PUT /api/annotations/:id
26
- def update_annotation( params ); end
213
+ #
214
+ # @param [Hash] params
215
+ # @option params [Integer] annotation
216
+ # @option params [Integer] time
217
+ # @option params [Integer] time_end
218
+ # @option params [Boolean] region
219
+ # @option params [Array] tags
220
+ # @option params [String] text
221
+ #
222
+ # @example
223
+ # params = {
224
+ # annotation: 1,
225
+ # tags: [ 'deployment' ],
226
+ # text: 'git tag #1234'
227
+ # }
228
+ # update_annotation( params )
229
+ #
230
+ # @return [Hash]
231
+ #
232
+ def update_annotation( params )
233
+
234
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
235
+ raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
236
+
237
+ annotation_id = validate( params, required: true, var: 'annotation', type: Integer )
238
+ time = validate( params, required: false, var: 'time', type: Integer )
239
+ time_end = validate( params, required: false, var: 'time_end', type: Integer )
240
+ region = validate( params, required: false, var: 'region', type: Boolean )
241
+ tags = validate( params, required: false, var: 'tags', type: Array )
242
+ text = validate( params, required: false, var: 'text', type: String )
243
+
244
+ unless( time_end.nil? )
245
+ return { 'status' => 404, 'message' => format( '\'end_time\' can\'t be lower then \'time\'' ) } if( time_end < time )
246
+ end
247
+
248
+ endpoint = format( '/api/annotations/%d', annotation_id)
249
+ payload = {
250
+ time: time,
251
+ timeEnd: time_end,
252
+ isRegion: region,
253
+ text: text,
254
+ tags: tags
255
+ }
256
+ payload.reject!{ |_k, v| v.nil? }
257
+
258
+ put(endpoint, payload.to_json)
259
+ end
27
260
 
28
261
  # Delete Annotation By Id
262
+ #
263
+ # Deletes the annotation that matches the specified id.
264
+ #
29
265
  # http://docs.grafana.org/http_api/annotations/#delete-annotation-by-id
30
266
  # DELETE /api/annotation/:id
31
- def delete_annotation( params ); end
267
+ #
268
+ # @param [Integer] annotation_id
269
+ #
270
+ # @example
271
+ # delete_annotation( 1 )
272
+ #
273
+ # @return [Hash]
274
+ #
275
+ def delete_annotation( annotation_id )
276
+
277
+ raise ArgumentError.new(format('wrong type. user \'annotation_id\' must be an Integer, given \'%s\'', annotation_id.class.to_s)) unless( annotation_id.is_a?(Integer) )
278
+ raise ArgumentError.new('missing \'annotation_id\'') if( annotation_id.size.zero? )
279
+ raise ArgumentError.new('\'annotation_id\' can not be 0') if( annotation_id.zero? )
280
+
281
+ endpoint = format( '/api/annotation/%d', annotation_id )
282
+
283
+ delete(endpoint)
284
+ end
32
285
 
33
286
  # Delete Annotation By RegionId
287
+ #
288
+ # Deletes the annotation that matches the specified region id.
289
+ # A region is an annotation that covers a timerange and has a start and end time.
290
+ # In the Grafana database, this is a stored as two annotations connected by a region id.
291
+ #
34
292
  # http://docs.grafana.org/http_api/annotations/#delete-annotation-by-regionid
35
293
  # DELETE /api/annotation/region/:id
36
- def delete_annotation_by_region( params ); end
294
+ #
295
+ # @param [Integer] region_id
296
+ #
297
+ # @example
298
+ # delete_annotation_by_region( 1 )
299
+ #
300
+ # @return [Hash]
301
+ #
302
+ def delete_annotation_by_region( region_id )
303
+
304
+ raise ArgumentError.new(format('wrong type. user \'region_id\' must be an Integer, given \'%s\'', region_id.class.to_s)) unless( region_id.is_a?(Integer) )
305
+ raise ArgumentError.new('missing \'region_id\'') if( region_id.size.zero? )
306
+ # raise ArgumentError.new('\'region_id\' can not be 0') if( region_id.zero? )
307
+
308
+ endpoint = format( '/api/annotation/region/%d', region_id )
309
+
310
+ delete(endpoint)
311
+ end
37
312
 
38
313
  end
39
314
 
@@ -12,14 +12,22 @@ require_relative 'network'
12
12
  require_relative 'tools'
13
13
  require_relative 'admin'
14
14
  require_relative 'annotations'
15
+ require_relative 'preferences'
15
16
  require_relative 'user'
16
17
  require_relative 'users'
18
+ require_relative 'teams'
17
19
  require_relative 'datasource'
18
20
  require_relative 'organization'
19
21
  require_relative 'organizations'
20
22
  require_relative 'dashboard'
21
23
  require_relative 'dashboard_versions'
24
+ require_relative 'dashboard_permissions'
22
25
  require_relative 'snapshot'
26
+ require_relative 'alerts'
27
+ require_relative 'folder'
28
+ require_relative 'folder_permissions'
29
+ require_relative 'folder_and_dashboard_search'
30
+ require_relative 'playlist'
23
31
 
24
32
  # -------------------------------------------------------------------------------------------------------------------
25
33
  #
@@ -46,14 +54,22 @@ module Grafana
46
54
  include Grafana::Tools
47
55
  include Grafana::Admin
48
56
  include Grafana::Annotations
57
+ include Grafana::Preferences
49
58
  include Grafana::User
50
59
  include Grafana::Users
60
+ include Grafana::Teams
51
61
  include Grafana::Datasource
52
62
  include Grafana::Organization
53
63
  include Grafana::Organizations
54
64
  include Grafana::Dashboard
55
65
  include Grafana::DashboardVersions
66
+ include Grafana::DashboardPermissions
56
67
  include Grafana::Snapshot
68
+ include Grafana::Alerts
69
+ include Grafana::Folder
70
+ include Grafana::FolderPermissions
71
+ include Grafana::FolderSearch
72
+ include Grafana::Playlist
57
73
 
58
74
  attr_accessor :debug
59
75
 
@@ -98,6 +114,8 @@ module Grafana
98
114
  @http_headers = settings.dig(:grafana, :http_headers) || {}
99
115
  @debug = settings.dig(:debug) || false
100
116
 
117
+ @headers = {}
118
+
101
119
  raise ArgumentError.new('missing \'host\'') if( host.nil? )
102
120
 
103
121
  raise ArgumentError.new(format('wrong type. \'port\' must be an Integer, given \'%s\'', port.class.to_s)) unless( port.is_a?(Integer) )
@@ -107,11 +125,30 @@ module Grafana
107
125
  raise ArgumentError.new(format('wrong type. \'open_timeout\' must be an Integer, given \'%s\'', @open_timeout.class.to_s)) unless( @open_timeout.is_a?(Integer) )
108
126
 
109
127
  protocoll = ssl == true ? 'https' : 'http'
110
- raise ArgumentError.new(format('wrong \'protocoll\'. only \'http\' or \'https\' allowed, given \'%s\'', protocoll)) if( %w[http https].include?(protocoll.downcase) == false )
111
128
 
112
129
  @url = format( '%s://%s:%d%s', protocoll, host, port, url_path )
113
130
  end
114
131
 
132
+ # Get Settings
133
+ #
134
+ # http://docs.grafana.org/http_api/other/#get-settings
135
+ #
136
+ def settings
137
+ endpoint = '/api/frontend/settings'
138
+ @logger.debug("Getting all settings (GET #{endpoint})") if @debug
139
+ get(endpoint)
140
+ end
141
+
142
+
143
+ def version
144
+ s = settings
145
+ @version = s.dig('buildInfo','version')
146
+ @major_version = @version.split('.').first.to_i
147
+
148
+ {version: @version, major_version: @major_version}
149
+ end
150
+
151
+
115
152
  def self.logger
116
153
  @@logger ||= defined?(Logging) ? Logging.logger : Logger.new(STDOUT)
117
154
  end
@@ -2,59 +2,186 @@
2
2
  module Grafana
3
3
 
4
4
  # http://docs.grafana.org/http_api/dashboard/
5
+
6
+ # The identifier (id) of a dashboard is an auto-incrementing numeric value and is only unique per Grafana install.
7
+ #
8
+ # The unique identifier (uid) of a dashboard can be used for uniquely identify a dashboard between multiple Grafana installs.
9
+ # It's automatically generated if not provided when creating a dashboard. The uid allows having consistent URL's for
10
+ # accessing dashboards and when syncing dashboards between multiple Grafana installs, see dashboard provisioning for
11
+ # more information. This means that changing the title of a dashboard will not break any bookmarked links to that dashboard.
12
+ #
13
+ # The uid can have a maximum length of 40 characters.
14
+ #
15
+ # Deprecated resources
16
+ # Please note that these resource have been deprecated and will be removed in a future release.
17
+ #
18
+ # - Get dashboard by slug
19
+ # - Delete dashboard by slug
20
+ #
21
+ #
5
22
  #
6
23
  module Dashboard
7
24
 
8
-
25
+ # http://docs.grafana.org/http_api/dashboard/#get-dashboard-by-slug
26
+ # - Deprecated starting from Grafana v5.0.
27
+ # Please update to use the new Get dashboard by uid resource instead
28
+ #
9
29
  # Get dashboard
10
- # GET /api/dashboards/db/:slug
30
+ #
31
+ # Will return the dashboard given the dashboard slug.
32
+ # Slug is the url friendly version of the dashboard title.
33
+ # If there exists multiple dashboards with the same slug, one of them will be returned in the response.
34
+ #
35
+ # @example
36
+ # dashboard('dashboard for many foo')
37
+ #
38
+ # @return [String]
39
+ #
11
40
  def dashboard( name )
12
41
 
13
42
  raise ArgumentError.new(format('wrong type. \'name\' must be an String, given \'%s\'', name.class.to_s)) unless( name.is_a?(String) )
14
43
  raise ArgumentError.new('missing name') if( name.size.zero? )
15
44
 
16
- # raise ArgumentError.new('name must be an String') unless( name.is_a?(String) )
45
+ # v, mv = version.values
46
+ #
47
+ # if( mv == 5)
48
+ # puts 'DEPRICATION WARNING'
49
+ # puts 'Grafana v5.0 use a new interal id/uid handling'
50
+ # puts 'This function works well with Grafana v4.x'
51
+ # end
17
52
 
18
53
  endpoint = format( '/api/dashboards/db/%s', slug(name) )
54
+ @logger.debug( "Attempting to get dashboard (GET #{endpoint})" ) if @debug
19
55
 
20
- @logger.debug( "Attempting to get dashboard (GET /api/dashboards/db/#{name})" ) if @debug
56
+ get( endpoint )
57
+ end
58
+
59
+ # http://docs.grafana.org/http_api/dashboard/#get-dashboard-by-uid
60
+ #
61
+ # GET /api/dashboards/uid/:uid
62
+ # Will return the dashboard given the dashboard unique identifier (uid).
63
+ #
64
+ # Get dashboard
65
+ #
66
+ # Will return the dashboard given the dashboard unique identifier (uid).
67
+ #
68
+ # @example
69
+ # dashboard('L42r6NWiz')
70
+ #
71
+ # @return [String]
72
+ #
73
+ def dashboard_by_uid( uid )
74
+
75
+ if( uid.is_a?(String) && uid.is_a?(Integer) )
76
+ raise ArgumentError.new(format('wrong type. dashboard \'uid\' must be an String (for an title name) or an Integer (for an Datasource Id), given \'%s\'', uid.class.to_s))
77
+ end
78
+ raise ArgumentError.new('missing \'uid\'') if( uid.size.zero? )
79
+
80
+ v, mv = version.values
81
+ return { 'status' => 404, 'message' => format( 'uid has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
82
+
83
+ return { 'status' => 404, 'message' => format( 'The uid can have a maximum length of 40 characters, but it is %s characters long', uid.length) } if( uid.length > 40 )
84
+
85
+ endpoint = format( '/api/dashboards/uid/%s', uid )
86
+ @logger.debug( "Attempting to get dashboard (GET #{endpoint})" ) if @debug
21
87
 
22
88
  get( endpoint )
23
89
  end
24
90
 
25
91
  # Create / Update dashboard
92
+ #
93
+ # Creates a new dashboard or updates an existing dashboard.
94
+ #
95
+ # @param [Hash] params
96
+ # @option params [Hash] dashboard The complete dashboard model
97
+ # - dashboard.id - id = null to create a new dashboard.
98
+ # - dashboard.uid - Optional unique identifier when creating a dashboard. uid = null will generate a new uid.
99
+ # - folderId - The id of the folder to save the dashboard in.
100
+ # - overwrite - Set to true if you want to overwrite existing dashboard with newer version, same dashboard title in folder or same dashboard uid.
101
+ # - message - Set a commit message for the version history.
102
+ # @option params [Boolean] overwrite (true)
103
+ #
104
+ # @example
105
+ # params = {
106
+ # dashboard: {
107
+ # id: null,
108
+ # uid: null,
109
+ # title: 'Production Overview',
110
+ # tags: [ 'templated' ],
111
+ # timezone": 'browser',
112
+ # rows: [
113
+ # {
114
+ # }
115
+ # ],
116
+ # 'schemaVersion': 6,
117
+ # 'version': 0
118
+ # },
119
+ # folderId: 0,
120
+ # overwrite: false,
121
+ # message: 'created by foo'
122
+ # }
123
+ # create_dashboard( params )
124
+ #
125
+ # @return [Hash]
126
+ #
26
127
  # POST /api/dashboards/db
27
128
  def create_dashboard( params )
28
129
 
29
- raise ArgumentError.new(format('wrong type. params must be an Hash, given %s', params.class.to_s ) ) unless( params.is_a?(Hash) )
30
-
31
- title = params.dig(:title)
32
- dashboard = params.dig(:dashboard)
130
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
131
+ raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
33
132
 
34
- # raise ArgumentError.new('missing title') if( title.nil? )
35
- raise ArgumentError.new('missing dashboard') if( dashboard.nil? )
36
- raise ArgumentError.new(format('wrong type. dashboard must be an Hash, given %s', dashboard.class.to_s ) ) unless( dashboard.is_a?(Hash) )
133
+ dashboard = validate( params, required: true , var: 'dashboard', type: Hash )
134
+ overwrite = validate( params, required: false, var: 'overwrite', type: Boolean ) || true
135
+ folder_id = validate( params, required: false, var: 'folderId' )
136
+ message = validate( params, required: false, var: 'message', type: String )
37
137
 
38
- endpoint = '/api/dashboards/db'
39
- # title = slug(title)
40
-
41
- # dashboard = JSON.parse( dashboard ) if( dashboard.is_a?(String) )
42
138
  dashboard = regenerate_template_ids( dashboard )
43
139
 
44
- if( title.nil? )
45
- db = JSON.parse( dashboard ) if( dashboard.is_a?(String) )
46
- title = db.dig('dashboard','title')
140
+ unless(folder_id.nil?)
141
+ f_folder = folder(folder_id)
142
+ return { 'status' => 404, 'message' => format( 'No Folder \'%s\' found', folder_id) } if( f_folder.dig('status') != 200 )
143
+
144
+ folder_id = f_folder.dig('id')
47
145
  end
48
146
 
147
+ db = JSON.parse( dashboard ) if( dashboard.is_a?(String) )
148
+ title = db.dig('dashboard','title')
149
+ uid = db.dig('dashboard','uid')
150
+
151
+ return { 'status' => 404, 'message' => format( 'The template \'%s\' can\'t be create. The uid can have a maximum length of 40 characters, but it is %s characters long', title, uid.length) } if( ! uid.nil? && uid.length > 40 )
152
+
153
+ endpoint = '/api/dashboards/db'
154
+
155
+ payload = {
156
+ dashboard: db.dig('dashboard'),
157
+ overwrite: overwrite,
158
+ folderId: folder_id,
159
+ message: message
160
+ }
161
+ payload.reject!{ |_k, v| v.nil? }
162
+
49
163
  @logger.debug("Creating dashboard: #{title} (POST /api/dashboards/db)") if @debug
50
164
 
51
- post( endpoint, dashboard )
165
+ post( endpoint, payload.to_json )
52
166
  end
53
167
 
168
+ # http://docs.grafana.org/http_api/dashboard/#delete-dashboard-by-slug
169
+ # - Deprecated starting from Grafana v5.0.
170
+ # Please update to use the new Get dashboard by uid resource instead
171
+ #
54
172
  # Delete dashboard
55
- # DELETE /api/dashboards/db/:slug
173
+ # Will delete the dashboard given the specified slug. Slug is the url friendly version of the dashboard title.
174
+ #
175
+ # @example
176
+ # delete_dashboard('dashboard for many foo')
177
+ #
178
+ # @return [Hash]
179
+ #
56
180
  def delete_dashboard( name )
57
181
 
182
+ raise ArgumentError.new(format('wrong type. \'name\' must be an String, given \'%s\'', name.class.to_s)) unless( name.is_a?(String) )
183
+ raise ArgumentError.new('missing name') if( name.size.zero? )
184
+
58
185
  endpoint = format( '/api/dashboards/db/%s', slug(name) )
59
186
 
60
187
  @logger.debug("Deleting dashboard #{slug(name)} (DELETE #{endpoint})") if @debug
@@ -63,7 +190,12 @@ module Grafana
63
190
  end
64
191
 
65
192
  # Gets the home dashboard
66
- # GET /api/dashboards/home
193
+ #
194
+ # @example
195
+ # home_dashboard
196
+ #
197
+ # @return [Hash]
198
+ #
67
199
  def home_dashboard
68
200
 
69
201
  endpoint = '/api/dashboards/home'
@@ -74,7 +206,12 @@ module Grafana
74
206
  end
75
207
 
76
208
  # Tags for Dashboard
77
- # GET /api/dashboards/tags
209
+ #
210
+ # @example
211
+ # dashboard_tags
212
+ #
213
+ # @return [Hash]
214
+ #
78
215
  def dashboard_tags
79
216
 
80
217
  endpoint = '/api/dashboards/tags'
@@ -85,29 +222,30 @@ module Grafana
85
222
  end
86
223
 
87
224
  # Search Dashboards
88
- # GET /api/search/
89
225
  #
90
- # searchDashboards( { :tags => host } )
91
- # searchDashboards( { :tags => [ host, 'tag1' ] } )
92
- # searchDashboards( { :tags => [ 'tag2' ] } )
93
- # searchDashboards( { :query => title } )
94
- # searchDashboards( { :starred => true } )
95
- def search_dashboards( params = {} )
226
+ # @example
227
+ # searchDashboards( tags: host )
228
+ # searchDashboards( tags: [ host, 'tag1' ] )
229
+ # searchDashboards( tags: [ 'tag2' ] )
230
+ # searchDashboards( query: title )
231
+ # searchDashboards( starred: true )
232
+ #
233
+ # @return [Hash]
234
+ #
235
+ def search_dashboards( params )
96
236
 
97
237
  raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
98
238
 
99
- query = params.dig(:query)
100
- starred = params.dig(:starred)
101
- tags = params.dig(:tags)
102
- api = []
239
+ query = validate( params, required: false, var: 'query', type: String )
240
+ starred = validate( params, required: false, var: 'starred', type: Boolean )
241
+ tags = validate( params, required: false, var: 'tags' )
103
242
 
104
- api << format( 'query=%s', CGI.escape( query ) ) unless query.nil?
243
+ api = []
244
+ api << format( 'query=%s', CGI.escape( query ) ) unless( query.nil? )
105
245
  api << format( 'starred=%s', starred ? 'true' : 'false' ) unless( starred.nil? )
106
246
 
107
247
  unless( tags.nil? )
108
-
109
248
  tags = tags.join( '&tag=' ) if( tags.is_a?( Array ) )
110
-
111
249
  api << format( 'tag=%s', tags )
112
250
  end
113
251
 
@@ -120,7 +258,13 @@ module Grafana
120
258
  get( endpoint )
121
259
  end
122
260
 
123
-
261
+ # import Dashboards from directory
262
+ #
263
+ # @example
264
+ # import_dashboards_from_directory( '/tmp/dashboards' )
265
+ #
266
+ # @return [Hash]
267
+ #
124
268
  def import_dashboards_from_directory( directory )
125
269
 
126
270
  raise ArgumentError.new('directory must be an String') unless( directory.is_a?(String) )
@@ -135,10 +279,9 @@ module Grafana
135
279
 
136
280
  dashboard = File.read( f )
137
281
  dashboard = JSON.parse( dashboard )
138
- title = dashboard.dig('dashboard','title') || f
139
282
 
140
283
  result[f.to_s] ||= {}
141
- result[f.to_s] = create_dashboard( title: title, dashboard: dashboard )
284
+ result[f.to_s] = create_dashboard( dashboard: dashboard )
142
285
  end
143
286
 
144
287
  result