grafana 0.8.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +8 -3
- data/lib/grafana/admin.rb +39 -65
- data/lib/grafana/alerts.rb +334 -14
- data/lib/grafana/annotations.rb +284 -9
- data/lib/grafana/client.rb +38 -1
- data/lib/grafana/dashboard.rb +182 -39
- data/lib/grafana/dashboard_permissions.rb +132 -0
- data/lib/grafana/dashboard_versions.rb +101 -5
- data/lib/grafana/datasource.rb +93 -49
- data/lib/grafana/folder.rb +198 -0
- data/lib/grafana/folder_and_dashboard_search.rb +57 -0
- data/lib/grafana/folder_permissions.rb +155 -0
- data/lib/grafana/login.rb +41 -35
- data/lib/grafana/network.rb +128 -91
- data/lib/grafana/organization.rb +65 -34
- data/lib/grafana/organizations.rb +119 -175
- data/lib/grafana/playlist.rb +599 -0
- data/lib/grafana/preferences.rb +122 -0
- data/lib/grafana/tags.rb +19 -8
- data/lib/grafana/teams.rb +364 -0
- data/lib/grafana/tools.rb +44 -12
- data/lib/grafana/user.rb +78 -39
- data/lib/grafana/users.rb +104 -53
- data/lib/grafana/validator.rb +47 -2
- data/lib/grafana/version.rb +3 -3
- metadata +13 -38
- data/doc/Array.html +0 -200
- data/doc/Boolean.html +0 -122
- data/doc/FalseClass.html +0 -132
- data/doc/Grafana.html +0 -172
- data/doc/Hash.html +0 -212
- data/doc/Logging.html +0 -326
- data/doc/Object.html +0 -286
- data/doc/Time.html +0 -200
- data/doc/TrueClass.html +0 -132
- data/doc/_index.html +0 -380
- data/doc/class_list.html +0 -51
- data/doc/file.README.html +0 -117
- data/doc/file_list.html +0 -56
- data/doc/frames.html +0 -17
- data/doc/index.html +0 -117
- data/doc/method_list.html +0 -771
- data/doc/top-level-namespace.html +0 -112
data/lib/grafana/network.rb
CHANGED
@@ -3,77 +3,151 @@ module Grafana
|
|
3
3
|
|
4
4
|
module Network
|
5
5
|
|
6
|
+
# GET request
|
7
|
+
#
|
8
|
+
# @param endpoint [String]
|
9
|
+
#
|
6
10
|
def get( endpoint )
|
7
|
-
|
8
11
|
request( 'GET', endpoint )
|
9
12
|
end
|
10
13
|
|
14
|
+
# POST request
|
15
|
+
#
|
16
|
+
# @param endpoint [String]
|
17
|
+
# @param data [Hash]
|
18
|
+
#
|
11
19
|
def post( endpoint, data )
|
12
|
-
|
13
20
|
request( 'POST', endpoint, data )
|
14
21
|
end
|
15
22
|
|
23
|
+
# PUT request
|
24
|
+
#
|
25
|
+
# @param endpoint [String]
|
26
|
+
# @param data [Hash]
|
27
|
+
#
|
16
28
|
def put( endpoint, data )
|
17
|
-
|
18
29
|
request( 'PUT', endpoint, data )
|
19
30
|
end
|
20
31
|
|
32
|
+
# PATCH request
|
33
|
+
#
|
34
|
+
# @param endpoint [String]
|
35
|
+
# @param data [Hash]
|
36
|
+
#
|
21
37
|
def patch( endpoint, data )
|
22
|
-
|
23
38
|
request( 'PATCH', endpoint, data )
|
24
39
|
end
|
25
40
|
|
41
|
+
# DELETE request
|
42
|
+
#
|
43
|
+
# @param endpoint [String]
|
44
|
+
#
|
26
45
|
def delete( endpoint )
|
27
|
-
|
28
46
|
request( 'DELETE', endpoint )
|
29
47
|
end
|
30
48
|
|
49
|
+
|
50
|
+
private
|
51
|
+
# helper function for all request methods
|
52
|
+
#
|
53
|
+
# @param method_type [String]
|
54
|
+
# @param endpoint [String]
|
55
|
+
# @param data [Hash]
|
56
|
+
#
|
57
|
+
# @example
|
58
|
+
#
|
59
|
+
#
|
60
|
+
# @return [Hash]
|
61
|
+
#
|
31
62
|
def request( method_type = 'GET', endpoint = '/', data = {} )
|
32
63
|
|
33
|
-
raise 'try first login()' if
|
64
|
+
raise 'try first login()' if @api_instance.nil?
|
65
|
+
|
66
|
+
login( username: @username, password: @password )
|
34
67
|
|
35
68
|
response = nil
|
36
69
|
response_code = 404
|
37
70
|
response_body = ''
|
38
71
|
|
39
72
|
begin
|
40
|
-
|
41
73
|
case method_type.upcase
|
42
74
|
when 'GET'
|
43
|
-
response = @api_instance[endpoint].get(
|
75
|
+
response = @api_instance[endpoint].get( headers )
|
44
76
|
when 'POST'
|
45
|
-
response = @api_instance[endpoint].post( data,
|
77
|
+
response = @api_instance[endpoint].post( data, headers )
|
46
78
|
when 'PATCH'
|
47
|
-
response = @api_instance[endpoint].patch( data,
|
79
|
+
response = @api_instance[endpoint].patch( data, headers )
|
48
80
|
when 'PUT'
|
49
|
-
# response = @api_instance[endpoint].put( data, @headers )
|
50
|
-
@api_instance[endpoint].put( data, @headers ) do |response, request, result|
|
51
81
|
|
52
|
-
|
82
|
+
# response = @api_instance[endpoint].put( data, headers )
|
83
|
+
@api_instance[endpoint].put( data, headers ) do |resp, _request, _result|
|
84
|
+
|
85
|
+
response_code = resp.code.to_i
|
86
|
+
response_body = resp.body
|
87
|
+
response_body = JSON.parse(response_body) if response_body.is_a?(String)
|
88
|
+
|
89
|
+
#logger.debug( "code : #{response_code}" )
|
90
|
+
#logger.debug( "message: #{response_body}" )
|
91
|
+
|
92
|
+
case response_code.to_i
|
53
93
|
when 200
|
54
|
-
response_body
|
55
|
-
response_code = response.code.to_i
|
56
|
-
response_body = JSON.parse(response_body) if response_body.is_a?(String)
|
57
|
-
|
58
|
-
return {
|
59
|
-
'status' => response_code,
|
60
|
-
'message' => response_body.dig('message').nil? ? 'Successful' : response_body.dig('message')
|
61
|
-
}
|
94
|
+
return { 'status' => response_code, 'message' => response_body.dig('message').nil? ? 'Successful' : response_body.dig('message') }
|
62
95
|
when 400
|
63
|
-
response_body = response.body
|
64
|
-
response_code = response.code.to_i
|
65
96
|
raise RestClient::BadRequest
|
97
|
+
when 412
|
98
|
+
status = response_body.dig('status')
|
99
|
+
message = response_body.dig('message')
|
100
|
+
message += " (#{status})" unless(status.nil?)
|
101
|
+
return { 'status' => response_code, 'message' => message }
|
102
|
+
when 422
|
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
|
66
117
|
else
|
67
|
-
logger.error(
|
68
|
-
logger.error(
|
69
|
-
|
118
|
+
# logger.error( response_code )
|
119
|
+
# logger.error( response_body )
|
120
|
+
return { 'status' => response_code, 'message' => response_body.dig('message') }
|
121
|
+
# response.return! # (request, result)
|
70
122
|
end
|
71
123
|
end
|
72
124
|
|
73
125
|
when 'DELETE'
|
74
|
-
|
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
|
+
|
75
149
|
else
|
76
|
-
|
150
|
+
logger.error( "Error: #{__method__} is not a valid request method." )
|
77
151
|
return false
|
78
152
|
end
|
79
153
|
|
@@ -81,89 +155,52 @@ module Grafana
|
|
81
155
|
response_body = response.body
|
82
156
|
response_headers = response.headers
|
83
157
|
|
84
|
-
if( @debug )
|
85
|
-
logger.debug("response_code : #{response_code}" )
|
86
|
-
logger.debug("response_body : #{response_body}" )
|
87
|
-
logger.debug("response_headers : #{response_headers}" )
|
88
|
-
end
|
89
|
-
|
90
158
|
if( ( response_code >= 200 && response_code <= 299 ) || ( response_code >= 400 && response_code <= 499 ) )
|
91
159
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
'message' => result
|
98
|
-
}
|
99
|
-
return r_result
|
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 }
|
100
165
|
end
|
101
166
|
|
102
|
-
result_status
|
103
|
-
|
167
|
+
result_status = result.dig('status') if( result.is_a?( Hash ) )
|
104
168
|
result['message'] = result_status unless( result_status.nil? )
|
105
169
|
result['status'] = response_code
|
106
170
|
|
107
171
|
return result
|
108
172
|
else
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
@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 ) )
|
113
176
|
|
114
177
|
return JSON.parse( response_body )
|
115
178
|
end
|
116
179
|
|
117
180
|
rescue RestClient::BadRequest
|
118
|
-
|
119
181
|
response_body = JSON.parse(response_body) if response_body.is_a?(String)
|
120
|
-
|
121
|
-
return {
|
122
|
-
'status' => 400,
|
123
|
-
'message' => response_body.dig('message').nil? ? 'Bad Request' : response_body.dig('message')
|
124
|
-
}
|
125
|
-
|
182
|
+
return { 'status' => 400, 'message' => response_body.dig('message').nil? ? 'Bad Request' : response_body.dig('message') }
|
126
183
|
rescue RestClient::Unauthorized
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
'message' => format('Not authorized to connect \'%s/%s\' - wrong username or password?', @url, endpoint)
|
131
|
-
}
|
132
|
-
|
184
|
+
return { 'status' => 401, 'message' => format('Not authorized to connect \'%s/%s\' - wrong username or password?', @url, endpoint) }
|
185
|
+
rescue RestClient::Forbidden
|
186
|
+
return { 'status' => 403, 'message' => format('The operation is forbidden \'%s/%s\'', @url, endpoint) }
|
133
187
|
rescue RestClient::NotFound
|
134
|
-
|
135
|
-
return {
|
136
|
-
'status' => 404,
|
137
|
-
'message' => 'Not Found'
|
138
|
-
}
|
139
|
-
|
188
|
+
return { 'status' => 404, 'message' => 'Not Found' }
|
140
189
|
rescue RestClient::Conflict
|
141
|
-
|
142
|
-
return {
|
143
|
-
'status' => 409,
|
144
|
-
'message' => 'Conflict with the current state of the target resource'
|
145
|
-
}
|
146
|
-
|
190
|
+
return { 'status' => 409, 'message' => 'Conflict with the current state of the target resource' }
|
147
191
|
rescue RestClient::PreconditionFailed
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
}
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
logger.error( "Error: #{__method__} #{method_type.upcase} on #{endpoint} error: '#{
|
157
|
-
logger.error( data )
|
158
|
-
|
159
|
-
logger.error( JSON.pretty_generate( response_headers ) )
|
160
|
-
|
161
|
-
return false
|
162
|
-
|
192
|
+
return { 'status' => 412, 'message' => 'Precondition failed. The Object probably already exists.' }
|
193
|
+
rescue RestClient::PreconditionFailed
|
194
|
+
return { 'status' => 412, 'message' => 'Precondition failed. The Object probably already exists.' }
|
195
|
+
rescue RestClient::ExceptionWithResponse => error
|
196
|
+
#logger.error( "Error: (RestClient::ExceptionWithResponse) #{__method__} #{method_type.upcase} on #{endpoint} error: '#{error}'" )
|
197
|
+
#logger.error( "query: #{data}" )
|
198
|
+
return { 'status' => 500, 'message' => "Internal Server Error: #{error}" }
|
199
|
+
rescue => error
|
200
|
+
#logger.error( "Error: #{__method__} #{method_type.upcase} on #{endpoint} error: '#{error}'" )
|
201
|
+
#logger.error( "query: #{data}" )
|
202
|
+
return { 'status' => 500, 'message' => "Internal Server Error: #{error}" }
|
163
203
|
end
|
164
|
-
|
165
204
|
end
|
166
|
-
|
167
205
|
end
|
168
|
-
|
169
206
|
end
|
data/lib/grafana/organization.rb
CHANGED
@@ -6,9 +6,11 @@ module Grafana
|
|
6
6
|
module Organization
|
7
7
|
|
8
8
|
# Get current Organisation
|
9
|
-
# GET /api/org
|
10
9
|
#
|
11
|
-
#
|
10
|
+
# @example
|
11
|
+
# current_organization
|
12
|
+
#
|
13
|
+
# @return [Hash]
|
12
14
|
#
|
13
15
|
def current_organization
|
14
16
|
endpoint = '/api/org'
|
@@ -17,25 +19,40 @@ module Grafana
|
|
17
19
|
end
|
18
20
|
|
19
21
|
# Update current Organisation
|
20
|
-
# PUT /api/org
|
21
22
|
#
|
23
|
+
# @param [Hash] params
|
24
|
+
# @option params [String] name new Organisation Name
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# params = {
|
28
|
+
# name: 'foo'
|
29
|
+
# }
|
30
|
+
# update_current_organization( params )
|
22
31
|
#
|
32
|
+
# @return [Hash]
|
23
33
|
#
|
24
|
-
def update_current_organization( params
|
34
|
+
def update_current_organization( params )
|
25
35
|
|
26
36
|
raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
|
27
|
-
|
28
|
-
|
37
|
+
raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
|
38
|
+
|
39
|
+
name = validate( params, required: true, var: 'name', type: String )
|
29
40
|
|
30
41
|
endpoint = '/api/org'
|
42
|
+
payload = {
|
43
|
+
name: name
|
44
|
+
}
|
45
|
+
|
31
46
|
@logger.debug("Updating current organization (PUT #{endpoint})") if @debug
|
32
|
-
put(endpoint,
|
47
|
+
put(endpoint, payload.to_json)
|
33
48
|
end
|
34
49
|
|
35
50
|
# Get all users within the actual organisation
|
36
|
-
# GET /api/org/users
|
37
51
|
#
|
52
|
+
# @example
|
53
|
+
# current_organization_users
|
38
54
|
#
|
55
|
+
# @return [Hash]
|
39
56
|
#
|
40
57
|
def current_organization_users
|
41
58
|
endpoint = '/api/org/users'
|
@@ -44,46 +61,60 @@ module Grafana
|
|
44
61
|
end
|
45
62
|
|
46
63
|
# Add a new user to the actual organisation
|
47
|
-
# POST /api/org/users
|
48
64
|
#
|
65
|
+
# @param [Hash] params
|
66
|
+
# @option params [String] login_or_email Login or email
|
67
|
+
# @option params [String] role Name of the Role - only 'Viewer', 'Editor', 'Read Only Editor' or 'Admin' allowed
|
68
|
+
#
|
69
|
+
# @example
|
70
|
+
# params = {
|
71
|
+
# login_or_email: 'foo',
|
72
|
+
# role: 'Editor'
|
73
|
+
# }
|
74
|
+
# add_user_to_current_organization( params )
|
49
75
|
#
|
76
|
+
# @return [Hash]
|
50
77
|
#
|
51
|
-
def add_user_to_current_organization( params
|
78
|
+
def add_user_to_current_organization( params )
|
52
79
|
|
53
80
|
raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
|
54
|
-
|
55
|
-
role = params.dig(:role)
|
56
|
-
raise ArgumentError.new('missing loginOrEmail') if( login_or_email.nil? )
|
57
|
-
raise ArgumentError.new('missing role') if( role.nil? )
|
58
|
-
# Defaults to Viewer, other valid options are Admin and Editor and Read Only Editor
|
59
|
-
# valid_perms = ['Viewer','Editor','Read Only Editor','Admin']
|
60
|
-
raise ArgumentError.new( format( 'wrong role. only \'Admin\', \'Viewer\' or \'Editor\' allowed (\'%s\' giving)',role)) if( %w[Admin Viewer Editor].include?(role) == false )
|
61
|
-
|
62
|
-
org = current_organization_users
|
63
|
-
usr = user_by_name( login_or_email )
|
64
|
-
|
65
|
-
if( org )
|
66
|
-
|
67
|
-
org = org.dig('message')
|
81
|
+
raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
|
68
82
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
'message' => format('User \'%s\' are already in the organisation', login_or_email)
|
73
|
-
}
|
74
|
-
end
|
75
|
-
end
|
83
|
+
login_or_email = validate( params, required: true, var: 'login_or_email', type: String )
|
84
|
+
role = validate( params, required: true, var: 'role', type: String )
|
85
|
+
valid_roles = ['Viewer', 'Editor', 'Read Only Editor', 'Admin']
|
76
86
|
|
77
|
-
|
87
|
+
# https://stackoverflow.com/questions/9333952/case-insensitive-arrayinclude?answertab=votes#tab-top
|
88
|
+
# Do this once, or each time the array changes
|
89
|
+
downcased = Set.new valid_roles.map(&:downcase)
|
90
|
+
unless( downcased.include?( role.downcase ) )
|
78
91
|
return {
|
79
92
|
'status' => 404,
|
80
|
-
'
|
93
|
+
'login_or_email' => login_or_email,
|
94
|
+
'role' => role,
|
95
|
+
'message' => format( 'wrong role. Role must be one of %s, given \'%s\'', valid_roles.join(', '), role )
|
81
96
|
}
|
82
97
|
end
|
83
98
|
|
99
|
+
org = current_organization_users
|
100
|
+
usr = user( login_or_email )
|
101
|
+
|
102
|
+
return { 'status' => 404, 'message' => format('User \'%s\' not found', login_or_email) } if( usr.nil? || usr.dig('status').to_i != 200 )
|
103
|
+
|
104
|
+
if( org.is_a?(Hash) && org.dig('status').to_i == 200 )
|
105
|
+
org = org.dig('message')
|
106
|
+
return { 'status' => 404, 'message' => format('User \'%s\' are already in the organisation', login_or_email) } \
|
107
|
+
if( org.select { |x| x.dig('email') == login_or_email || x.dig('login') == login_or_email }.count >= 1 )
|
108
|
+
end
|
109
|
+
|
84
110
|
endpoint = '/api/org/users'
|
111
|
+
payload = {
|
112
|
+
loginOrEmail: login_or_email,
|
113
|
+
role: role
|
114
|
+
}
|
115
|
+
|
85
116
|
@logger.debug("Adding user to current organization (POST #{endpoint})") if @debug
|
86
|
-
post(endpoint,
|
117
|
+
post(endpoint, payload.to_json)
|
87
118
|
end
|
88
119
|
|
89
120
|
# Updates the given user
|
@@ -13,7 +13,6 @@ module Grafana
|
|
13
13
|
get( endpoint )
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
16
|
# Get a single data sources by Id or Name
|
18
17
|
#
|
19
18
|
# @example
|
@@ -24,39 +23,20 @@ module Grafana
|
|
24
23
|
#
|
25
24
|
def organization( organisation_id )
|
26
25
|
|
27
|
-
|
26
|
+
if( organisation_id.is_a?(String) && organisation_id.is_a?(Integer))
|
27
|
+
raise ArgumentError.new(format('wrong type. \'organisation_id\' must be an String (for an Datasource name) ' \
|
28
|
+
'or an Integer (for an Datasource Id), given \'%s\'', organisation_id.class.to_s))
|
29
|
+
end
|
28
30
|
raise ArgumentError.new('missing \'organisation_id\'') if( organisation_id.size.zero? )
|
29
31
|
|
30
32
|
endpoint = format( '/api/orgs/%d', organisation_id ) if(organisation_id.is_a?(Integer))
|
31
|
-
endpoint = format( '/api/orgs/name/%s',
|
33
|
+
endpoint = format( '/api/orgs/name/%s', ERB::Util.url_encode( organisation_id ) ) if(organisation_id.is_a?(String))
|
32
34
|
|
33
35
|
@logger.debug("Attempting to get existing data source Id #{organisation_id} (GET #{endpoint})") if @debug
|
34
36
|
|
35
37
|
get(endpoint)
|
36
38
|
end
|
37
39
|
|
38
|
-
# # Get Organisation by Id
|
39
|
-
# # GET /api/orgs/:orgId
|
40
|
-
# def organization_by_id( id )
|
41
|
-
#
|
42
|
-
# raise ArgumentError.new('id must be an Integer') unless( id.is_a?(Integer) )
|
43
|
-
#
|
44
|
-
# endpoint = format( '/api/orgs/%d', id )
|
45
|
-
# @logger.debug("Get Organisation by Id (GET #{endpoint}})") if @debug
|
46
|
-
# get( endpoint )
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
# # Get Organisation by Name
|
50
|
-
# # GET /api/orgs/name/:orgName
|
51
|
-
# def organization_by_name( name )
|
52
|
-
#
|
53
|
-
# raise ArgumentError.new('name must be an String') unless( name.is_a?(String) )
|
54
|
-
#
|
55
|
-
# endpoint = format( '/api/orgs/name/%s', URI.escape( name ) )
|
56
|
-
# @logger.debug("Get Organisation by Name (GET #{endpoint})") if @debug
|
57
|
-
# get( endpoint )
|
58
|
-
# end
|
59
|
-
|
60
40
|
# Update Organisation
|
61
41
|
#
|
62
42
|
# fields Adress 1, Adress 2, City are not implemented yet.
|
@@ -78,30 +58,25 @@ module Grafana
|
|
78
58
|
raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
|
79
59
|
raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
|
80
60
|
|
81
|
-
organization
|
82
|
-
name
|
61
|
+
organization = validate( params, required: true, var: 'organization', type: String )
|
62
|
+
name = validate( params, required: true, var: 'name', type: String )
|
63
|
+
org = organization( organization )
|
83
64
|
|
84
|
-
|
65
|
+
return { 'status' => 404, 'message' => format('Organization \'%s\' not found', organization) } if( org.nil? || org.dig('status').to_i != 200 )
|
85
66
|
|
86
|
-
|
87
|
-
return {
|
88
|
-
'status' => 404,
|
89
|
-
'message' => format('Organization \'%s\' not found', organization)
|
90
|
-
}
|
91
|
-
end
|
92
|
-
org_id = org.dig('id')
|
67
|
+
organization_id = org.dig('id')
|
93
68
|
|
69
|
+
endpoint = format( '/api/orgs/%s', organization_id )
|
94
70
|
payload = { name: name }
|
95
71
|
|
96
|
-
|
97
|
-
@logger.debug("Update Organisation id #{org_id} (PUT #{endpoint})") if @debug
|
72
|
+
@logger.debug("Update Organisation id #{organization_id} (PUT #{endpoint})") if @debug
|
98
73
|
|
99
74
|
put( endpoint, payload.to_json )
|
100
75
|
end
|
101
76
|
|
102
77
|
# Get Users in Organisation
|
103
78
|
#
|
104
|
-
# @param [Mixed]
|
79
|
+
# @param [Mixed] organization_id Organistaion Name (String) or Organistaion Id (Integer)
|
105
80
|
#
|
106
81
|
# @example
|
107
82
|
# organization_users( 1 )
|
@@ -109,36 +84,35 @@ module Grafana
|
|
109
84
|
#
|
110
85
|
# @return [Hash]
|
111
86
|
#
|
112
|
-
def organization_users(
|
87
|
+
def organization_users( organization_id )
|
113
88
|
|
114
|
-
|
115
|
-
|
89
|
+
if( organization_id.is_a?(String) && organization_id.is_a?(Integer))
|
90
|
+
raise ArgumentError.new(format('wrong type. \'organization_id\' must be an String (for an Organisation name) '\
|
91
|
+
'or an Integer (for an Organisation Id), given \'%s\'', organization_id.class.to_s))
|
92
|
+
end
|
93
|
+
raise ArgumentError.new('missing \'organization_id\'') if( organization_id.size.zero? )
|
116
94
|
|
117
|
-
if(
|
118
|
-
org = organization(
|
119
|
-
if( org.nil? || org.dig('status').to_i != 200 )
|
120
|
-
|
121
|
-
|
122
|
-
'message' => format('Organization \'%s\' not found', organization)
|
123
|
-
}
|
124
|
-
end
|
125
|
-
org_id = org.dig('id')
|
95
|
+
if(organization_id.is_a?(String))
|
96
|
+
org = organization(organization_id)
|
97
|
+
return { 'status' => 404, 'message' => format('Organization \'%s\' not found', organization) } if( org.nil? || org.dig('status').to_i != 200 )
|
98
|
+
|
99
|
+
organization_id = org.dig('id')
|
126
100
|
end
|
127
101
|
|
128
|
-
endpoint = format( '/api/orgs/%s/users',
|
102
|
+
endpoint = format( '/api/orgs/%s/users', organization_id )
|
129
103
|
|
130
|
-
@logger.debug("Getting users in Organisation id #{
|
104
|
+
@logger.debug("Getting users in Organisation id #{organization_id} (GET #{endpoint})") if @debug
|
131
105
|
get(endpoint)
|
132
106
|
end
|
133
107
|
|
134
108
|
# Add User in Organisation
|
135
109
|
#
|
136
|
-
# @param
|
110
|
+
# @param [Hash] params
|
137
111
|
# @option params [String] organization Organisation name
|
138
112
|
# @option params [String] login_or_email Login or email
|
139
113
|
# @option params [String] role Name of the Role - only 'Viewer', 'Editor', 'Read Only Editor' or 'Admin' allowed
|
140
114
|
#
|
141
|
-
# @
|
115
|
+
# @example
|
142
116
|
# params = {
|
143
117
|
# organization: 'Foo',
|
144
118
|
# login_or_email: 'foo@foo-bar.tld',
|
@@ -150,54 +124,25 @@ module Grafana
|
|
150
124
|
#
|
151
125
|
def add_user_to_organization( params )
|
152
126
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
organization = validate( params, required: true, var: 'organization', type: String )
|
157
|
-
login_or_email = validate( params, required: true, var: 'login_or_email', type: String )
|
158
|
-
role = validate( params, required: true, var: 'role', type: String )
|
159
|
-
valid_roles = ['Viewer', 'Editor', 'Read Only Editor', 'Admin']
|
160
|
-
|
161
|
-
# https://stackoverflow.com/questions/9333952/case-insensitive-arrayinclude?answertab=votes#tab-top
|
162
|
-
# Do this once, or each time the array changes
|
163
|
-
downcased = Set.new valid_roles.map(&:downcase)
|
164
|
-
unless( downcased.include?( role.downcase ) )
|
165
|
-
|
166
|
-
message = format( 'wrong role. Role must be one of %s, given \'%s\'', valid_roles.join(', '), role )
|
167
|
-
|
168
|
-
return {
|
169
|
-
'status' => 404,
|
170
|
-
'login_or_email' => login_or_email,
|
171
|
-
'role' => role,
|
172
|
-
'message' => message
|
173
|
-
}
|
174
|
-
end
|
175
|
-
|
176
|
-
org = organization( organization )
|
177
|
-
usr = user_by_name( login_or_email )
|
127
|
+
data = validate_organisation_user( params )
|
128
|
+
status = data.dig('status')
|
178
129
|
|
179
|
-
if(
|
180
|
-
return {
|
181
|
-
'status' => 404,
|
182
|
-
'message' => format('Organization \'%s\' not found', organization)
|
183
|
-
}
|
184
|
-
end
|
130
|
+
return data if( status.nil? || status.to_i == 404 )
|
185
131
|
|
186
|
-
|
187
|
-
|
188
|
-
'status' => 404,
|
189
|
-
'message' => format('User \'%s\' not found', login_or_email)
|
190
|
-
}
|
191
|
-
end
|
132
|
+
org = data.dig('organisation')
|
133
|
+
usr = data.dig('user')
|
192
134
|
|
193
|
-
|
135
|
+
organization_id = org.dig('id')
|
136
|
+
organization = org.dig('name')
|
137
|
+
login_or_email = usr.dig('email')
|
138
|
+
role = data.dig('role')
|
194
139
|
|
140
|
+
endpoint = format( '/api/orgs/%d/users', organization_id )
|
195
141
|
payload = {
|
196
142
|
loginOrEmail: login_or_email,
|
197
143
|
role: role
|
198
144
|
}
|
199
145
|
|
200
|
-
endpoint = format( '/api/orgs/%d/users', org_id )
|
201
146
|
@logger.debug("Adding user '#{login_or_email}' to organisation '#{organization}' (POST #{endpoint})") if @debug
|
202
147
|
|
203
148
|
post( endpoint, payload.to_json )
|
@@ -205,12 +150,12 @@ module Grafana
|
|
205
150
|
|
206
151
|
# Update Users in Organisation
|
207
152
|
#
|
208
|
-
# @param
|
153
|
+
# @param [Hash] params
|
209
154
|
# @option params [String] organization Organisation name
|
210
155
|
# @option params [String] login_or_email Login or email
|
211
156
|
# @option params [String] role Name of the Role - only 'Viewer', 'Editor', 'Read Only Editor' or 'Admin' allowed
|
212
157
|
#
|
213
|
-
# @
|
158
|
+
# @example
|
214
159
|
# params = {
|
215
160
|
# organization: 'Foo',
|
216
161
|
# login_or_email: 'foo@foo-bar.tld',
|
@@ -222,67 +167,36 @@ module Grafana
|
|
222
167
|
#
|
223
168
|
def update_organization_user( params )
|
224
169
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
organization = validate( params, required: true, var: 'organization', type: String )
|
229
|
-
login_or_email = validate( params, required: true, var: 'login_or_email', type: String )
|
230
|
-
role = validate( params, required: true, var: 'role', type: String )
|
231
|
-
valid_roles = ['Viewer', 'Editor', 'Read Only Editor', 'Admin']
|
232
|
-
|
233
|
-
# https://stackoverflow.com/questions/9333952/case-insensitive-arrayinclude?answertab=votes#tab-top
|
234
|
-
# Do this once, or each time the array changes
|
235
|
-
downcased = Set.new valid_roles.map(&:downcase)
|
236
|
-
unless( downcased.include?( role.downcase ) )
|
237
|
-
|
238
|
-
message = format( 'wrong role. Role must be one of %s, given \'%s\'', valid_roles.join(', '), role )
|
239
|
-
|
240
|
-
return {
|
241
|
-
'status' => 404,
|
242
|
-
'login_or_email' => login_or_email,
|
243
|
-
'role' => role,
|
244
|
-
'message' => message
|
245
|
-
}
|
246
|
-
end
|
247
|
-
|
248
|
-
org = organization( organization )
|
249
|
-
usr = user_by_name( login_or_email )
|
170
|
+
data = validate_organisation_user( params )
|
171
|
+
status = data.dig('status')
|
250
172
|
|
251
|
-
if(
|
252
|
-
return {
|
253
|
-
'status' => 404,
|
254
|
-
'message' => format('Organization \'%s\' not found', organization)
|
255
|
-
}
|
256
|
-
end
|
173
|
+
return data if( status.nil? || status.to_i == 404 )
|
257
174
|
|
258
|
-
|
259
|
-
|
260
|
-
'status' => 404,
|
261
|
-
'message' => format('User \'%s\' not found', login_or_email)
|
262
|
-
}
|
263
|
-
end
|
175
|
+
org = data.dig('organisation')
|
176
|
+
usr = data.dig('user')
|
264
177
|
|
265
|
-
|
178
|
+
organization_id = org.dig('id')
|
179
|
+
organization = org.dig('name')
|
266
180
|
usr_id = usr.dig('id')
|
181
|
+
login_or_email = usr.dig('name')
|
182
|
+
role = data.dig(:role)
|
267
183
|
|
184
|
+
endpoint = format( '/api/orgs/%d/users/%d', organization_id, usr_id )
|
268
185
|
payload = {
|
269
186
|
role: role
|
270
187
|
}
|
271
188
|
|
272
|
-
endpoint = format( '/api/orgs/%d/users/%d', org_id, usr_id )
|
273
|
-
|
274
189
|
@logger.debug("Updating user '#{login_or_email}' in organization '#{organization}' (PATCH #{endpoint})") if @debug
|
275
190
|
patch( endpoint, payload.to_json )
|
276
191
|
end
|
277
192
|
|
278
193
|
# Delete User in Organisation
|
279
194
|
#
|
280
|
-
# @param
|
195
|
+
# @param [Hash] params
|
281
196
|
# @option params [String] organization Organisation name
|
282
197
|
# @option params [String] login_or_email Login or email
|
283
|
-
# @option params [String] role Name of the Role - only 'Viewer', 'Editor', 'Read Only Editor' or 'Admin' allowed
|
284
198
|
#
|
285
|
-
# @
|
199
|
+
# @example
|
286
200
|
# params = {
|
287
201
|
# organization: 'Foo',
|
288
202
|
# login_or_email: 'foo@foo-bar.tld'
|
@@ -291,7 +205,6 @@ module Grafana
|
|
291
205
|
#
|
292
206
|
# @return [Hash]
|
293
207
|
#
|
294
|
-
# DELETE /api/orgs/:orgId/users/:userId
|
295
208
|
def delete_user_from_organization( params )
|
296
209
|
|
297
210
|
raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
|
@@ -301,26 +214,15 @@ module Grafana
|
|
301
214
|
login_or_email = validate( params, required: true, var: 'login_or_email', type: String )
|
302
215
|
|
303
216
|
org = organization( organization )
|
304
|
-
usr =
|
305
|
-
|
306
|
-
if( org.nil? || org.dig('status').to_i != 200 )
|
307
|
-
return {
|
308
|
-
'status' => 404,
|
309
|
-
'message' => format('Organization \'%s\' not found', organization)
|
310
|
-
}
|
311
|
-
end
|
217
|
+
usr = user( login_or_email )
|
312
218
|
|
313
|
-
if(
|
314
|
-
|
315
|
-
'status' => 404,
|
316
|
-
'message' => format('User \'%s\' not found', login_or_email)
|
317
|
-
}
|
318
|
-
end
|
219
|
+
return { 'status' => 404, 'message' => format('Organization \'%s\' not found', organization) } if( org.nil? || org.dig('status').to_i != 200 )
|
220
|
+
return { 'status' => 404, 'message' => format('User \'%s\' not found', login_or_email) } if( usr.nil? || usr.dig('status').to_i != 200 )
|
319
221
|
|
320
|
-
|
222
|
+
organization_id = org.dig('id')
|
321
223
|
usr_id = usr.dig('id')
|
322
224
|
|
323
|
-
endpoint = format( '/api/orgs/%d/users/%d',
|
225
|
+
endpoint = format( '/api/orgs/%d/users/%d', organization_id, usr_id )
|
324
226
|
|
325
227
|
@logger.debug("Deleting user '#{login_or_email}' in organization '#{organization}' (DELETE #{endpoint})") if @debug
|
326
228
|
delete(endpoint)
|
@@ -328,10 +230,10 @@ module Grafana
|
|
328
230
|
|
329
231
|
# Create Organisation
|
330
232
|
#
|
331
|
-
# @param
|
233
|
+
# @param [Hash] params
|
332
234
|
# @option params [String] organization Organisation name
|
333
235
|
#
|
334
|
-
# @
|
236
|
+
# @example
|
335
237
|
# params = {
|
336
238
|
# name: 'Foo'
|
337
239
|
# }
|
@@ -345,15 +247,9 @@ module Grafana
|
|
345
247
|
raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
|
346
248
|
|
347
249
|
name = validate( params, required: true, var: 'name', type: String )
|
250
|
+
org = organization( name )
|
348
251
|
|
349
|
-
|
350
|
-
|
351
|
-
if( org.nil? || org.dig('status').to_i == 200 )
|
352
|
-
return {
|
353
|
-
'status' => 409,
|
354
|
-
'message' => format('Organisation \'%s\' already exists', name )
|
355
|
-
}
|
356
|
-
end
|
252
|
+
return { 'status' => 409, 'message' => format('Organisation \'%s\' already exists', name ) } if( org.nil? || org.dig('status').to_i == 200 )
|
357
253
|
|
358
254
|
endpoint = '/api/orgs'
|
359
255
|
payload = {
|
@@ -376,31 +272,79 @@ module Grafana
|
|
376
272
|
#
|
377
273
|
def delete_organisation( organisation_id )
|
378
274
|
|
379
|
-
|
275
|
+
if( organisation_id.is_a?(String) && organisation_id.is_a?(Integer) )
|
276
|
+
raise ArgumentError.new(format('wrong type. \'organisation_id\' must be an String (for an Organisation name) ' \
|
277
|
+
'or an Integer (for an Organisation Id), given \'%s\'', organisation_id.class.to_s))
|
278
|
+
end
|
380
279
|
raise ArgumentError.new('missing \'organisation_id\'') if( organisation_id.size.zero? )
|
381
280
|
|
382
281
|
if(organisation_id.is_a?(String))
|
383
282
|
data = organizations.dig('message')
|
384
283
|
organisation_map = {}
|
385
|
-
data.each do |
|
386
|
-
organisation_map[
|
284
|
+
data.each do |d|
|
285
|
+
organisation_map[d.dig('id')] = d.dig('name')
|
387
286
|
end
|
388
|
-
organisation_map.select { |
|
389
|
-
organisation_id = organisation_map.keys.first if( data )
|
287
|
+
organisation_id = organisation_map.select { |_,y| y == organisation_id }.keys.first if( organisation_map )
|
390
288
|
end
|
391
289
|
|
392
|
-
if( organisation_id.nil? )
|
290
|
+
return { 'status' => 404, 'message' => format( 'No Organisation \'%s\' found', organisation_id) } if( organisation_id.nil? )
|
291
|
+
|
292
|
+
endpoint = format( '/api/orgs/%d', organisation_id )
|
293
|
+
@logger.debug("Deleting organization #{organisation_id} (DELETE #{endpoint})") if @debug
|
294
|
+
|
295
|
+
delete(endpoint)
|
296
|
+
end
|
297
|
+
|
298
|
+
|
299
|
+
private
|
300
|
+
# validate an user for an organisation
|
301
|
+
#
|
302
|
+
# @example
|
303
|
+
# params = {
|
304
|
+
# organization: 'Foo',
|
305
|
+
# login_or_email: 'foo@foo-bar.tld',
|
306
|
+
# role: 'Viewer'
|
307
|
+
# }
|
308
|
+
# validate_organisation_user( params )
|
309
|
+
#
|
310
|
+
# @return [Hash]
|
311
|
+
#
|
312
|
+
def validate_organisation_user( 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
|
+
organization = validate( params, required: true, var: 'organization', type: String )
|
318
|
+
login_or_email = validate( params, required: true, var: 'login_or_email', type: String )
|
319
|
+
role = validate( params, required: true, var: 'role', type: String )
|
320
|
+
valid_roles = ['Viewer', 'Editor', 'Read Only Editor', 'Admin']
|
321
|
+
|
322
|
+
# https://stackoverflow.com/questions/9333952/case-insensitive-arrayinclude?answertab=votes#tab-top
|
323
|
+
# Do this once, or each time the array changes
|
324
|
+
downcased = Set.new valid_roles.map(&:downcase)
|
325
|
+
unless( downcased.include?( role.downcase ) )
|
393
326
|
return {
|
394
327
|
'status' => 404,
|
395
|
-
'
|
328
|
+
'login_or_email' => login_or_email,
|
329
|
+
'role' => role,
|
330
|
+
'message' => format( 'wrong role. Role must be one of %s, given \'%s\'', valid_roles.join(', '), role )
|
396
331
|
}
|
397
332
|
end
|
398
333
|
|
399
|
-
|
400
|
-
|
334
|
+
org = organization( organization )
|
335
|
+
usr = user( login_or_email )
|
401
336
|
|
402
|
-
|
337
|
+
return { 'status' => 404, 'message' => format('Organization \'%s\' not found', organization) } if( org.nil? || org.dig('status').to_i != 200 )
|
338
|
+
return { 'status' => 404, 'message' => format('User \'%s\' not found', login_or_email) } if( usr.nil? || usr.dig('status').to_i != 200 )
|
339
|
+
|
340
|
+
{
|
341
|
+
'status' => 200,
|
342
|
+
'organisation' => org,
|
343
|
+
'user' => usr,
|
344
|
+
'role' => role
|
345
|
+
}
|
403
346
|
end
|
404
347
|
|
348
|
+
|
405
349
|
end
|
406
350
|
end
|