grafana 0.10.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d62ca27f8f2d01a27309e9b947fa2f633caf75d2bcc94443a9208c36416ff5e3
4
- data.tar.gz: 30f9a883ac3b492ea294a090960f733c7a163d59c39975c3efb12391410387af
3
+ metadata.gz: 8e73fd657e1a344d3cb67b5bf01cd33f8e227447e92e6e93b575a51a0091a253
4
+ data.tar.gz: c9f41ad884326c341d9c25746bfb80967206c5d0f94ef2bf94a4de6dd7e74435
5
5
  SHA512:
6
- metadata.gz: 81a9b8b26d5de44f741045268ce8fc4eb0581414cecba178abea7e8c614be0c2586256ace00669719b87eee37c47c90e1fb9a0c5d23171a236ff49938caf3934
7
- data.tar.gz: f680c1a86f1aa778eb00e440fc00d290683bafc0eb245c67215c071079ad8ca43b6499e54ee9aeee2bd6dd15f7c89eff9a86b6ebfd70604a831f1717169b528c
6
+ metadata.gz: 4aa2e43dbde3b105b5f85c74ac84a4269cd67d2de6b327cc597854ef1e6e4d66ce52628e9564785a0f1729527e90514e2577c83a651d8fe6c82c765c73a8ecbc
7
+ data.tar.gz: 50df29f0e9ad79c5dd7586dd1190585badb8ae3e09b82847433721cded33a6aa562ccba34be65c12356ca00cde64a45a18bf9dde1592af614a52263d71bca2f4
data/README.md CHANGED
@@ -26,9 +26,14 @@ TODO: Write usage instructions here
26
26
 
27
27
  ## Development
28
28
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rake` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
-
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
29
+ After checking out the repo, run `bin/setup` to install dependencies.
30
+ Then, run `rake rake` to run the tests.
31
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
32
+
33
+ To install this gem onto your local machine, run `bundle exec rake install`.
34
+ To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`,
35
+ which will create a git tag for the version,
36
+ push git commits and tags and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
37
 
33
38
  ## Contributing
34
39
 
@@ -27,6 +27,7 @@ require_relative 'alerts'
27
27
  require_relative 'folder'
28
28
  require_relative 'folder_permissions'
29
29
  require_relative 'folder_and_dashboard_search'
30
+ require_relative 'playlist'
30
31
 
31
32
  # -------------------------------------------------------------------------------------------------------------------
32
33
  #
@@ -68,6 +69,7 @@ module Grafana
68
69
  include Grafana::Folder
69
70
  include Grafana::FolderPermissions
70
71
  include Grafana::FolderSearch
72
+ include Grafana::Playlist
71
73
 
72
74
  attr_accessor :debug
73
75
 
@@ -78,7 +78,7 @@ module Grafana
78
78
  raise ArgumentError.new('missing \'uid\'') if( uid.size.zero? )
79
79
 
80
80
  v, mv = version.values
81
- return { 'status' => 404, 'message' => format( 'only Grafana 5 has uid support. you use version %s', v) } if(mv != 5)
81
+ return { 'status' => 404, 'message' => format( 'uid has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
82
82
 
83
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
84
 
@@ -148,7 +148,7 @@ module Grafana
148
148
  title = db.dig('dashboard','title')
149
149
  uid = db.dig('dashboard','uid')
150
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 )
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
152
 
153
153
  endpoint = '/api/dashboards/db'
154
154
 
@@ -51,7 +51,7 @@ module Grafana
51
51
  raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
52
52
 
53
53
  v, mv = version.values
54
- return { 'status' => 404, 'message' => format( 'only Grafana 5 has folder support. you use version %s', v) } if(mv != 5)
54
+ return { 'status' => 404, 'message' => format( 'folder has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
55
55
 
56
56
  dashboard_id = validate( params, required: true, var: 'dashboard_id', type: Integer )
57
57
  permissions = validate( params, required: true, var: 'permissions' , type: Hash )
@@ -20,7 +20,7 @@ module Grafana
20
20
  raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
21
21
 
22
22
  # v, mv = version.values
23
- # return { 'status' => 404, 'message' => format( 'only Grafana 5 has dashboard version support. you use version %s', v) } if(mv != 5)
23
+ # return { 'status' => 404, 'message' => format( 'dashboard has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
24
24
 
25
25
  dashboard_id = validate( params, required: true , var: 'dashboard_id', type: Integer )
26
26
  start = validate( params, required: false, var: 'start' , type: Integer )
@@ -44,7 +44,7 @@ module Grafana
44
44
  raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
45
45
 
46
46
  v, mv = version.values
47
- return { 'status' => 404, 'message' => format( 'only Grafana 5 has folder support. you use version %s', v) } if(mv != 5)
47
+ return { 'status' => 404, 'message' => format( 'folder has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
48
48
 
49
49
  dashboard_id = validate( params, required: true, var: 'dashboard_id', type: Integer )
50
50
  version = validate( params, required: true, var: 'version' , type: Integer )
@@ -67,7 +67,7 @@ module Grafana
67
67
  raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
68
68
 
69
69
  # v, mv = version.values
70
- # return { 'status' => 404, 'message' => format( 'only Grafana 5 has folder support. you use version %s', v) } if(mv != 5)
70
+ # return { 'status' => 404, 'message' => format( 'folder has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
71
71
 
72
72
  dashboard_id = validate( params, required: true, var: 'dashboard_id', type: Integer )
73
73
  version = validate( params, required: true, var: 'version' , type: Integer )
@@ -16,7 +16,7 @@ module Grafana
16
16
  def folders
17
17
 
18
18
  v, mv = version.values
19
- return { 'status' => 404, 'message' => format( 'only Grafana 5 has folder support. you use version %s', v) } if(mv != 5)
19
+ return { 'status' => 404, 'message' => format( 'folder has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
20
20
 
21
21
  endpoint = '/api/folders'
22
22
  @logger.debug("Getting all folders (GET #{endpoint})") if @debug
@@ -39,7 +39,7 @@ module Grafana
39
39
  raise ArgumentError.new('missing \'folder_uid\'') if( folder_uid.size.zero? )
40
40
 
41
41
  v, mv = version.values
42
- return { 'status' => 404, 'message' => format( 'only Grafana 5 has folder support. you use version %s', v) } if(mv != 5)
42
+ return { 'status' => 404, 'message' => format( 'folder has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
43
43
 
44
44
  if(folder_uid.is_a?(Integer))
45
45
 
@@ -58,7 +58,7 @@ module Grafana
58
58
  return { 'status' => 404, 'message' => format( 'No Folder \'%s\' found', folder_uid) } if( folder_uid.is_a?(Integer) )
59
59
  end
60
60
 
61
- return { 'status' => 404, 'message' => format( 'The uid can have a maximum length of 40 characters. \'%s\' given', folder_uid.length) } \
61
+ return { 'status' => 404, 'message' => format( 'The uid can have a maximum length of 40 characters, but it is %s characters long', folder_uid.length) } \
62
62
  if( folder_uid.is_a?(String) && folder_uid.length > 40 )
63
63
  return { 'status' => 404, 'message' => format( 'No Folder \'%s\' found', folder_uid) } if( folder_uid.nil? )
64
64
 
@@ -82,7 +82,7 @@ module Grafana
82
82
  raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
83
83
 
84
84
  v, mv = version.values
85
- return { 'status' => 404, 'message' => format( 'only Grafana 5 has folder support. you use version %s', v) } if(mv != 5)
85
+ return { 'status' => 404, 'message' => format( 'folder has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
86
86
 
87
87
  title = validate( params, required: false, var: 'title', type: String )
88
88
  uid = validate( params, required: true , var: 'uid' , type: String )
@@ -124,7 +124,7 @@ module Grafana
124
124
  raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
125
125
 
126
126
  v, mv = version.values
127
- return { 'status' => 404, 'message' => format( 'only Grafana 5 has folder support. you use version %s', v) } if(mv != 5)
127
+ return { 'status' => 404, 'message' => format( 'folder has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
128
128
 
129
129
  uid = validate( params, required: true , var: 'uid' , type: String )
130
130
  title = validate( params, required: true , var: 'title' , type: String )
@@ -168,7 +168,7 @@ module Grafana
168
168
  raise ArgumentError.new('missing \'folder_uid\'') if( folder_uid.size.zero? )
169
169
 
170
170
  v, mv = version.values
171
- return { 'status' => 404, 'message' => format( 'only Grafana 5 has folder support. you use version %s', v) } if(mv != 5)
171
+ return { 'status' => 404, 'message' => format( 'folder has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
172
172
 
173
173
  if(folder_uid.is_a?(Integer))
174
174
 
@@ -21,7 +21,7 @@ module Grafana
21
21
  raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
22
22
 
23
23
  v, mv = version.values
24
- return { 'status' => 404, 'message' => format( 'only Grafana 5 has team support. you use version %s', v) } if(mv != 5)
24
+ return { 'status' => 404, 'message' => format( 'team has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
25
25
 
26
26
  query = validate( params, required: false, var: 'query' , type: String )
27
27
  tag = validate( params, required: false, var: 'tag ' , type: String )
@@ -23,7 +23,7 @@ module Grafana
23
23
  def folder_permissions( folder_id )
24
24
 
25
25
  v, mv = version.values
26
- return { 'status' => 404, 'message' => format( 'only Grafana 5 has folder support. you use version %s', v) } if(mv != 5)
26
+ return { 'status' => 404, 'message' => format( 'folder has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
27
27
 
28
28
  f = folder( folder_id )
29
29
 
@@ -53,7 +53,7 @@ module Grafana
53
53
  raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
54
54
 
55
55
  v, mv = version.values
56
- return { 'status' => 404, 'message' => format( 'only Grafana 5 has folder support. you use version %s', v) } if(mv != 5)
56
+ return { 'status' => 404, 'message' => format( 'folder has been supported in Grafana since version 5. you use version %s', v) } if(mv < 5)
57
57
 
58
58
  folder = validate( params, required: true, var: 'folder' , type: String )
59
59
  permissions = validate( params, required: true, var: 'permissions', type: Hash )
data/lib/grafana/login.rb CHANGED
@@ -131,8 +131,8 @@ module Grafana
131
131
  # @return [Hash]
132
132
  #
133
133
  def ping_session
134
- endpoint = '/api/login/ping'
135
134
  logger.debug( "Pinging current session (GET #{endpoint})" ) if @debug
135
+ endpoint = '/api/login/ping'
136
136
  get( endpoint )
137
137
  end
138
138
 
@@ -60,7 +60,7 @@ module Grafana
60
60
  # @return [Hash]
61
61
  #
62
62
  def request( method_type = 'GET', endpoint = '/', data = {} )
63
- # logger.debug( "request( #{method_type}, #{endpoint}, data )" )
63
+
64
64
  raise 'try first login()' if @api_instance.nil?
65
65
 
66
66
  login( username: @username, password: @password )
@@ -78,13 +78,18 @@ module Grafana
78
78
  when 'PATCH'
79
79
  response = @api_instance[endpoint].patch( data, headers )
80
80
  when 'PUT'
81
+
81
82
  # response = @api_instance[endpoint].put( data, headers )
82
83
  @api_instance[endpoint].put( data, headers ) do |resp, _request, _result|
83
- response_body = resp.body
84
+
84
85
  response_code = resp.code.to_i
86
+ response_body = resp.body
85
87
  response_body = JSON.parse(response_body) if response_body.is_a?(String)
86
88
 
87
- case response_code
89
+ #logger.debug( "code : #{response_code}" )
90
+ #logger.debug( "message: #{response_body}" )
91
+
92
+ case response_code.to_i
88
93
  when 200
89
94
  return { 'status' => response_code, 'message' => response_body.dig('message').nil? ? 'Successful' : response_body.dig('message') }
90
95
  when 400
@@ -95,19 +100,54 @@ module Grafana
95
100
  message += " (#{status})" unless(status.nil?)
96
101
  return { 'status' => response_code, 'message' => message }
97
102
  when 422
98
- raise RestClient::UnprocessableEntity
103
+ logger.error('422')
104
+
105
+ response_body = response_body.first if(response_body.is_a?(Array))
106
+ message_field_name = response_body.dig('fieldNames')
107
+
108
+ #status = response_code # response_body.dig('status')
109
+ message = response_body # .dig('message')
110
+ #message += " (#{status})" unless(status.nil?)
111
+
112
+ # [{fieldNames"=>["Id"], "classification"=>"RequiredError", "message"=>"Required"}]
113
+
114
+ logger.error(message)
115
+ return { 'status' => response_code, 'message' => message }
116
+ # #raise RestClient::UnprocessableEntity
99
117
  else
100
- # logger.error( response_code )
101
- # logger.error( response_body )
118
+ # logger.error( response_code )
119
+ # logger.error( response_body )
102
120
  return { 'status' => response_code, 'message' => response_body.dig('message') }
103
121
  # response.return! # (request, result)
104
122
  end
105
123
  end
106
124
 
107
125
  when 'DELETE'
108
- response = @api_instance[endpoint].delete( headers )
126
+
127
+ @api_instance[endpoint].delete( headers ) do |resp, _request, _result|
128
+
129
+ response_code = resp.code.to_i
130
+ response_body = resp.body
131
+ response_body = JSON.parse(response_body) if response_body.is_a?(String)
132
+
133
+ #logger.debug( "code : #{response_code}" )
134
+ #logger.debug( "message: #{response_body}" )
135
+
136
+ case response_code.to_i
137
+ when 200
138
+ return { 'status' => response_code, 'message' => response_body.dig('message').nil? ? 'Successful' : response_body.dig('message') }
139
+ when 404
140
+ return { 'status' => response_code, 'message' => response_body.dig('message').nil? ? 'Successful' : response_body.dig('message') }
141
+ else
142
+ # logger.error( response_code )
143
+ # logger.error( response_body )
144
+ return { 'status' => response_code, 'message' => response_body.dig('message') }
145
+ end
146
+
147
+ end
148
+
109
149
  else
110
- @logger.error( "Error: #{__method__} is not a valid request method." )
150
+ logger.error( "Error: #{__method__} is not a valid request method." )
111
151
  return false
112
152
  end
113
153
 
@@ -115,16 +155,14 @@ module Grafana
115
155
  response_body = response.body
116
156
  response_headers = response.headers
117
157
 
118
- # if( @debug )
119
- # logger.debug("response_code : #{response_code}" )
120
- # logger.debug("response_body : #{response_body}" )
121
- # logger.debug("response_headers : #{response_headers}" )
122
- # end
123
-
124
158
  if( ( response_code >= 200 && response_code <= 299 ) || ( response_code >= 400 && response_code <= 499 ) )
125
159
 
126
- result = JSON.parse( response_body )
127
- return { 'status' => response_code, 'message' => result } if( result.is_a?(Array) )
160
+ if( response_body =~ /^\[.*\]$/ || response_body =~ /^\{.*\}$/ )
161
+ result = JSON.parse( response_body )
162
+ return { 'status' => response_code, 'message' => result } if( result.is_a?(Array) )
163
+ else
164
+ return { 'status' => response_code, 'message' => response_body }
165
+ end
128
166
 
129
167
  result_status = result.dig('status') if( result.is_a?( Hash ) )
130
168
  result['message'] = result_status unless( result_status.nil? )
@@ -132,9 +170,9 @@ module Grafana
132
170
 
133
171
  return result
134
172
  else
135
- @logger.error( "#{__method__} #{method_type.upcase} on #{endpoint} failed: HTTP #{response.code} - #{response_body}" )
136
- @logger.error( headers )
137
- @logger.error( JSON.pretty_generate( response_headers ) )
173
+ logger.error( "#{__method__} #{method_type.upcase} on #{endpoint} failed: HTTP #{response.code} - #{response_body}" )
174
+ logger.error( headers )
175
+ logger.error( JSON.pretty_generate( response_headers ) )
138
176
 
139
177
  return JSON.parse( response_body )
140
178
  end
@@ -155,12 +193,12 @@ module Grafana
155
193
  rescue RestClient::PreconditionFailed
156
194
  return { 'status' => 412, 'message' => 'Precondition failed. The Object probably already exists.' }
157
195
  rescue RestClient::ExceptionWithResponse => error
158
- # logger.error( "Error: #{__method__} #{method_type.upcase} on #{endpoint} error: '#{error}'" )
159
- # logger.error( "query: #{data}" )
196
+ #logger.error( "Error: (RestClient::ExceptionWithResponse) #{__method__} #{method_type.upcase} on #{endpoint} error: '#{error}'" )
197
+ #logger.error( "query: #{data}" )
160
198
  return { 'status' => 500, 'message' => "Internal Server Error: #{error}" }
161
199
  rescue => error
162
- # logger.error( "Error: #{__method__} #{method_type.upcase} on #{endpoint} error: '#{error}'" )
163
- # logger.error( "query: #{data}" )
200
+ #logger.error( "Error: #{__method__} #{method_type.upcase} on #{endpoint} error: '#{error}'" )
201
+ #logger.error( "query: #{data}" )
164
202
  return { 'status' => 500, 'message' => "Internal Server Error: #{error}" }
165
203
  end
166
204
  end
@@ -30,7 +30,7 @@ module Grafana
30
30
  raise ArgumentError.new('missing \'organisation_id\'') if( organisation_id.size.zero? )
31
31
 
32
32
  endpoint = format( '/api/orgs/%d', organisation_id ) if(organisation_id.is_a?(Integer))
33
- endpoint = format( '/api/orgs/name/%s', URI.escape( organisation_id ) ) if(organisation_id.is_a?(String))
33
+ endpoint = format( '/api/orgs/name/%s', ERB::Util.url_encode( organisation_id ) ) if(organisation_id.is_a?(String))
34
34
 
35
35
  @logger.debug("Attempting to get existing data source Id #{organisation_id} (GET #{endpoint})") if @debug
36
36
 
@@ -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