grafana 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,139 @@
1
+
2
+ module Grafana
3
+
4
+ # Abstract base class for Login.
5
+ #
6
+ module Login
7
+
8
+ # Login into Grafana
9
+ #
10
+ # @param [Hash] params
11
+ # @option params [String] username username for the login
12
+ # @option params [String] password password for the login
13
+ # @option params [Integer] max_retries (2) maximum retries
14
+ # @option params [Integer] sleep_between_retries (5) sleep seconds between retries
15
+ #
16
+ # @example
17
+ # login( username: 'admin', password: 'admin' )
18
+ # login( username: 'admin', password: 'admin', max_retries: 10, sleep_between_retries: 8 )
19
+ #
20
+ # @return [Hash]
21
+ #
22
+ def login( params )
23
+
24
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
25
+ raise ArgumentError.new('missing params') if( params.size.zero? )
26
+
27
+ username = validate( params, required: true, var: 'username', type: String )
28
+ password = validate( params, required: true, var: 'password', type: String )
29
+ max_retries = validate( params, required: false, var: 'max_retries', type: Integer ) || 2
30
+ sleep_between_retries = validate( params, required: false, var: 'sleep_between_retries', type: Integer ) || 5
31
+
32
+ begin
33
+ @api_instance = RestClient::Resource.new(
34
+ @url,
35
+ timeout: @timeout.to_i,
36
+ open_timeout: @open_timeout.to_i,
37
+ headers: @http_headers,
38
+ verify_ssl: false
39
+ )
40
+ rescue => e
41
+ logger.error( e ) if @debug
42
+ logger.debug( e.backtrace.join("\n") ) if @debug
43
+ false
44
+ end
45
+
46
+ request_data = { 'User' => username, 'Password' => password }
47
+
48
+ if( @api_instance )
49
+ retried ||= 0
50
+ response_cookies = ''
51
+ @headers = {}
52
+
53
+ begin
54
+ logger.debug('Attempting to establish user session') if @debug
55
+
56
+ response = @api_instance['/login'].post(
57
+ request_data.to_json,
58
+ content_type: 'application/json; charset=UTF-8'
59
+ )
60
+
61
+ response_cookies = response.cookies
62
+ response_code = response.code.to_i
63
+
64
+ if( response_code == 200 )
65
+ @headers = {
66
+ content_type: 'application/json',
67
+ accept: 'application/json',
68
+ cookies: response_cookies
69
+ }
70
+ end
71
+
72
+ rescue SocketError
73
+ if( retried < max_retries )
74
+ retried += 1
75
+ logger.debug( format( 'cannot login, socket error (retry %d / %d)', retried, max_retries ) ) if @debug
76
+ sleep( sleep_between_retries )
77
+ retry
78
+ else
79
+ raise format( 'Maximum retries (%d) against \'%s/login\' reached. Giving up ...', max_retries, @url )
80
+ end
81
+
82
+ rescue RestClient::Unauthorized
83
+ logger.debug( request_data.to_json ) if @debug
84
+ raise format( 'Not authorized to connect \'%s\' - wrong username or password?', @url )
85
+
86
+ rescue RestClient::BadGateway
87
+ if( retried < max_retries )
88
+ retried += 1
89
+ logger.debug( format( 'cannot login, connection refused (retry %d / %d)', retried, max_retries ) ) if @debug
90
+ sleep( sleep_between_retries )
91
+ retry
92
+ else
93
+ raise format( 'Maximum retries (%d) against \'%s/login\' reached. Giving up ...', max_retries, @url )
94
+ end
95
+
96
+ rescue Errno::ECONNREFUSED
97
+ if( retried < max_retries )
98
+ retried += 1
99
+ logger.debug( format( 'cannot login, connection refused (retry %d / %d)', retried, max_retries ) ) if @debug
100
+ sleep( sleep_between_retries )
101
+ retry
102
+ else
103
+ raise format( 'Maximum retries (%d) against \'%s/login\' reached. Giving up ...', max_retries, @url )
104
+ end
105
+
106
+ rescue Errno::EHOSTUNREACH
107
+ if( retried < max_retries )
108
+ retried += 1
109
+ logger.debug( format( 'cannot login, host unreachable (retry %d / %d)', retried, max_retries ) ) if @debug
110
+ sleep( sleep_between_retries )
111
+ retry
112
+ else
113
+ raise format( 'Maximum retries (%d) against \'%s/login\' reached. Giving up ...', max_retries, @url )
114
+ end
115
+ end
116
+
117
+ logger.debug('User session initiated') if @debug
118
+
119
+ return true
120
+ end
121
+
122
+ false
123
+ end
124
+
125
+ # Renew session based on remember cookie
126
+ #
127
+ # @example
128
+ # ping_session
129
+ #
130
+ # @return [Hash]
131
+ #
132
+ def ping_session
133
+ endpoint = '/api/login/ping'
134
+ logger.debug( "Pinging current session (GET #{endpoint})" ) if @debug
135
+ get( endpoint )
136
+ end
137
+ end
138
+
139
+ end
@@ -0,0 +1,169 @@
1
+
2
+ module Grafana
3
+
4
+ module Network
5
+
6
+ def get( endpoint )
7
+
8
+ request( 'GET', endpoint )
9
+ end
10
+
11
+ def post( endpoint, data )
12
+
13
+ request( 'POST', endpoint, data )
14
+ end
15
+
16
+ def put( endpoint, data )
17
+
18
+ request( 'PUT', endpoint, data )
19
+ end
20
+
21
+ def patch( endpoint, data )
22
+
23
+ request( 'PATCH', endpoint, data )
24
+ end
25
+
26
+ def delete( endpoint )
27
+
28
+ request( 'DELETE', endpoint )
29
+ end
30
+
31
+ def request( method_type = 'GET', endpoint = '/', data = {} )
32
+
33
+ raise 'try first login()' if @api_instance.nil?
34
+
35
+ response = nil
36
+ response_code = 404
37
+ response_body = ''
38
+
39
+ begin
40
+
41
+ case method_type.upcase
42
+ when 'GET'
43
+ response = @api_instance[endpoint].get( @headers )
44
+ when 'POST'
45
+ response = @api_instance[endpoint].post( data, @headers )
46
+ when 'PATCH'
47
+ response = @api_instance[endpoint].patch( data, @headers )
48
+ when 'PUT'
49
+ # response = @api_instance[endpoint].put( data, @headers )
50
+ @api_instance[endpoint].put( data, @headers ) do |response, request, result|
51
+
52
+ case response.code
53
+ when 200
54
+ response_body = 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
+ }
62
+ when 400
63
+ response_body = response.body
64
+ response_code = response.code.to_i
65
+ raise RestClient::BadRequest
66
+ else
67
+ logger.error( response.code )
68
+ logger.error( response.body )
69
+ response.return! # (request, result)
70
+ end
71
+ end
72
+
73
+ when 'DELETE'
74
+ response = @api_instance[endpoint].delete( @headers )
75
+ else
76
+ @logger.error( "Error: #{__method__} is not a valid request method." )
77
+ return false
78
+ end
79
+
80
+ response_code = response.code.to_i
81
+ response_body = response.body
82
+ response_headers = response.headers
83
+
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
+ if( ( response_code >= 200 && response_code <= 299 ) || ( response_code >= 400 && response_code <= 499 ) )
91
+
92
+ result = JSON.parse( response_body )
93
+
94
+ if( result.is_a?(Array) )
95
+ r_result= {
96
+ 'status' => response_code,
97
+ 'message' => result
98
+ }
99
+ return r_result
100
+ end
101
+
102
+ result_status = result.dig('status') if( result.is_a?( Hash ) )
103
+
104
+ result['message'] = result_status unless( result_status.nil? )
105
+ result['status'] = response_code
106
+
107
+ return result
108
+ else
109
+
110
+ @logger.error( "#{__method__} #{method_type.upcase} on #{endpoint} failed: HTTP #{response.code} - #{response_body}" )
111
+ @logger.error( @headers )
112
+ @logger.error( JSON.pretty_generate( response_headers ) )
113
+
114
+ return JSON.parse( response_body )
115
+ end
116
+
117
+ rescue RestClient::BadRequest
118
+
119
+ 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
+
126
+ rescue RestClient::Unauthorized
127
+
128
+ return {
129
+ 'status' => 401,
130
+ 'message' => format('Not authorized to connect \'%s/%s\' - wrong username or password?', @url, endpoint)
131
+ }
132
+
133
+ rescue RestClient::NotFound
134
+
135
+ return {
136
+ 'status' => 404,
137
+ 'message' => 'Not Found'
138
+ }
139
+
140
+ rescue RestClient::Conflict
141
+
142
+ return {
143
+ 'status' => 409,
144
+ 'message' => 'Conflict with the current state of the target resource'
145
+ }
146
+
147
+ rescue RestClient::PreconditionFailed
148
+
149
+ return {
150
+ 'status' => 412,
151
+ 'message' => 'Precondition failed. The Object probably already exists.'
152
+ }
153
+
154
+ rescue RestClient::ExceptionWithResponse => e
155
+
156
+ logger.error( "Error: #{__method__} #{method_type.upcase} on #{endpoint} error: '#{e}'" )
157
+ logger.error( data )
158
+ logger.error( @headers )
159
+ logger.error( JSON.pretty_generate( response_headers ) )
160
+
161
+ return false
162
+
163
+ end
164
+
165
+ end
166
+
167
+ end
168
+
169
+ end
@@ -0,0 +1,101 @@
1
+
2
+ module Grafana
3
+
4
+ # http://docs.grafana.org/http_api/org/#organisation-api
5
+ #
6
+ module Organization
7
+
8
+ # Get current Organisation
9
+ # GET /api/org
10
+ #
11
+ # -> {"id"=>1, "name"=>"Docker", "address"=>{"address1"=>"", "address2"=>"", "city"=>"", "zipCode"=>"", "state"=>"", "country"=>""}, "status"=>200}
12
+ #
13
+ def current_organization
14
+ endpoint = '/api/org'
15
+ @logger.debug("Get current Organisation (GET #{endpoint})") if @debug
16
+ get(endpoint)
17
+ end
18
+
19
+ # Update current Organisation
20
+ # PUT /api/org
21
+ #
22
+ #
23
+ #
24
+ def update_current_organization( params = {} )
25
+
26
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
27
+ name = params.dig(:name)
28
+ raise ArgumentError.new('missing name') if( name.nil? )
29
+
30
+ endpoint = '/api/org'
31
+ @logger.debug("Updating current organization (PUT #{endpoint})") if @debug
32
+ put(endpoint, params.to_json)
33
+ end
34
+
35
+ # Get all users within the actual organisation
36
+ # GET /api/org/users
37
+ #
38
+ #
39
+ #
40
+ def current_organization_users
41
+ endpoint = '/api/org/users'
42
+ @logger.debug("Getting organization users (GET #{endpoint})") if @debug
43
+ get(endpoint)
44
+ end
45
+
46
+ # Add a new user to the actual organisation
47
+ # POST /api/org/users
48
+ #
49
+ #
50
+ #
51
+ def add_user_to_current_organization( params = {} )
52
+
53
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
54
+ login_or_email = params.dig(:loginOrEmail)
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')
68
+
69
+ if( org.select { |x| x.dig('email') == login_or_email }.count >= 1 )
70
+ return {
71
+ 'status' => 404,
72
+ 'message' => format('User \'%s\' are already in the organisation', login_or_email)
73
+ }
74
+ end
75
+ end
76
+
77
+ if( usr.nil? || usr.dig('status').to_i != 200 )
78
+ return {
79
+ 'status' => 404,
80
+ 'message' => format('User \'%s\' not found', login_or_email)
81
+ }
82
+ end
83
+
84
+ endpoint = '/api/org/users'
85
+ @logger.debug("Adding user to current organization (POST #{endpoint})") if @debug
86
+ post(endpoint, params.to_json)
87
+ end
88
+
89
+ # Updates the given user
90
+ # PATCH /api/org/users/:userId
91
+
92
+
93
+ # Delete user in actual organisation
94
+ # DELETE /api/org/users/:userId
95
+
96
+
97
+ #
98
+
99
+ end
100
+
101
+ end
@@ -0,0 +1,406 @@
1
+
2
+ module Grafana
3
+
4
+ # http://docs.grafana.org/http_api/org/#organisations
5
+ #
6
+ module Organizations
7
+
8
+ # Search all Organisations
9
+ # GET /api/orgs
10
+ def organizations
11
+ endpoint = '/api/orgs'
12
+ @logger.debug("Getting all organizations (GET #{endpoint})") if @debug
13
+ get( endpoint )
14
+ end
15
+
16
+
17
+ # Get a single data sources by Id or Name
18
+ #
19
+ # @example
20
+ # organisation( 1 )
21
+ # organisation( 'foo' )
22
+ #
23
+ # @return [Hash]
24
+ #
25
+ def organization( organisation_id )
26
+
27
+ raise ArgumentError.new(format('wrong type. user \'organisation_id\' must be an String (for an Datasource name) or an Integer (for an Datasource Id), given \'%s\'', organisation_id.class.to_s)) if( organisation_id.is_a?(String) && organisation_id.is_a?(Integer) )
28
+ raise ArgumentError.new('missing \'organisation_id\'') if( organisation_id.size.zero? )
29
+
30
+ endpoint = format( '/api/orgs/%d', organisation_id ) if(organisation_id.is_a?(Integer))
31
+ endpoint = format( '/api/orgs/name/%s', URI.escape( organisation_id ) ) if(organisation_id.is_a?(String))
32
+
33
+ @logger.debug("Attempting to get existing data source Id #{organisation_id} (GET #{endpoint})") if @debug
34
+
35
+ get(endpoint)
36
+ end
37
+
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
+ # Update Organisation
61
+ #
62
+ # fields Adress 1, Adress 2, City are not implemented yet.
63
+ #
64
+ # @param [Hash] params
65
+ # @option params [String] organization name of the Organisation
66
+ # @option params [String] name new name
67
+ # @option params [String] adress_1
68
+ # @option params [String] adress_2
69
+ # @option params [String] city
70
+ #
71
+ # @example
72
+ # update_organization( organization: 'Main. Org', name: 'Foo+Bar' )
73
+ #
74
+ # @return [Hash]
75
+ #
76
+ def update_organization( params )
77
+
78
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
79
+ raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
80
+
81
+ organization = validate( params, required: true, var: 'organization', type: String )
82
+ name = validate( params, required: true, var: 'name', type: String )
83
+
84
+ org = organization( organization )
85
+
86
+ if( org.nil? || org.dig('status').to_i != 200 )
87
+ return {
88
+ 'status' => 404,
89
+ 'message' => format('Organization \'%s\' not found', organization)
90
+ }
91
+ end
92
+ org_id = org.dig('id')
93
+
94
+ payload = { name: name }
95
+
96
+ endpoint = format( '/api/orgs/%s', org_id )
97
+ @logger.debug("Update Organisation id #{org_id} (PUT #{endpoint})") if @debug
98
+
99
+ put( endpoint, payload.to_json )
100
+ end
101
+
102
+ # Get Users in Organisation
103
+ #
104
+ # @param [Mixed] user_id Username (String) or Userid (Integer) for delete User
105
+ #
106
+ # @example
107
+ # organization_users( 1 )
108
+ # organization_users( 'Foo Bar' )
109
+ #
110
+ # @return [Hash]
111
+ #
112
+ def organization_users( org_id )
113
+
114
+ raise ArgumentError.new(format('wrong type. user \'org_id\' must be an String (for an Organisation name) or an Integer (for an Organisation Id), given \'%s\'', org_id.class.to_s)) if( org_id.is_a?(String) && org_id.is_a?(Integer) )
115
+ raise ArgumentError.new('missing \'org_id\'') if( org_id.size.zero? )
116
+
117
+ if(org_id.is_a?(String))
118
+ org = organization(org_id)
119
+ if( org.nil? || org.dig('status').to_i != 200 )
120
+ return {
121
+ 'status' => 404,
122
+ 'message' => format('Organization \'%s\' not found', organization)
123
+ }
124
+ end
125
+ org_id = org.dig('id')
126
+ end
127
+
128
+ endpoint = format( '/api/orgs/%s/users', org_id )
129
+
130
+ @logger.debug("Getting users in Organisation id #{org_id} (GET #{endpoint})") if @debug
131
+ get(endpoint)
132
+ end
133
+
134
+ # Add User in Organisation
135
+ #
136
+ # @param
137
+ # @option params [String] organization Organisation name
138
+ # @option params [String] login_or_email Login or email
139
+ # @option params [String] role Name of the Role - only 'Viewer', 'Editor', 'Read Only Editor' or 'Admin' allowed
140
+ #
141
+ # @examle
142
+ # params = {
143
+ # organization: 'Foo',
144
+ # login_or_email: 'foo@foo-bar.tld',
145
+ # role: 'Viewer'
146
+ # }
147
+ # add_user_to_organization( params )
148
+ #
149
+ # @return [Hash]
150
+ #
151
+ def add_user_to_organization( params )
152
+
153
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
154
+ raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
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 )
178
+
179
+ if( org.nil? || org.dig('status').to_i != 200 )
180
+ return {
181
+ 'status' => 404,
182
+ 'message' => format('Organization \'%s\' not found', organization)
183
+ }
184
+ end
185
+
186
+ if( usr.nil? || usr.dig('status').to_i != 200 )
187
+ return {
188
+ 'status' => 404,
189
+ 'message' => format('User \'%s\' not found', login_or_email)
190
+ }
191
+ end
192
+
193
+ org_id = org.dig('id')
194
+
195
+ payload = {
196
+ loginOrEmail: login_or_email,
197
+ role: role
198
+ }
199
+
200
+ endpoint = format( '/api/orgs/%d/users', org_id )
201
+ @logger.debug("Adding user '#{login_or_email}' to organisation '#{organization}' (POST #{endpoint})") if @debug
202
+
203
+ post( endpoint, payload.to_json )
204
+ end
205
+
206
+ # Update Users in Organisation
207
+ #
208
+ # @param
209
+ # @option params [String] organization Organisation name
210
+ # @option params [String] login_or_email Login or email
211
+ # @option params [String] role Name of the Role - only 'Viewer', 'Editor', 'Read Only Editor' or 'Admin' allowed
212
+ #
213
+ # @examle
214
+ # params = {
215
+ # organization: 'Foo',
216
+ # login_or_email: 'foo@foo-bar.tld',
217
+ # role: 'Viewer'
218
+ # }
219
+ # update_organization_user( params )
220
+ #
221
+ # @return [Hash]
222
+ #
223
+ def update_organization_user( params )
224
+
225
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
226
+ raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
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 )
250
+
251
+ if( org.nil? || org.dig('status').to_i != 200 )
252
+ return {
253
+ 'status' => 404,
254
+ 'message' => format('Organization \'%s\' not found', organization)
255
+ }
256
+ end
257
+
258
+ if( usr.nil? || usr.dig('status').to_i != 200 )
259
+ return {
260
+ 'status' => 404,
261
+ 'message' => format('User \'%s\' not found', login_or_email)
262
+ }
263
+ end
264
+
265
+ org_id = org.dig('id')
266
+ usr_id = usr.dig('id')
267
+
268
+ payload = {
269
+ role: role
270
+ }
271
+
272
+ endpoint = format( '/api/orgs/%d/users/%d', org_id, usr_id )
273
+
274
+ @logger.debug("Updating user '#{login_or_email}' in organization '#{organization}' (PATCH #{endpoint})") if @debug
275
+ patch( endpoint, payload.to_json )
276
+ end
277
+
278
+ # Delete User in Organisation
279
+ #
280
+ # @param
281
+ # @option params [String] organization Organisation name
282
+ # @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
+ #
285
+ # @examle
286
+ # params = {
287
+ # organization: 'Foo',
288
+ # login_or_email: 'foo@foo-bar.tld'
289
+ # }
290
+ # delete_user_from_organization( params )
291
+ #
292
+ # @return [Hash]
293
+ #
294
+ # DELETE /api/orgs/:orgId/users/:userId
295
+ def delete_user_from_organization( params )
296
+
297
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
298
+ raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
299
+
300
+ organization = validate( params, required: true, var: 'organization', type: String )
301
+ login_or_email = validate( params, required: true, var: 'login_or_email', type: String )
302
+
303
+ org = organization( organization )
304
+ usr = user_by_name( login_or_email )
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
312
+
313
+ if( usr.nil? || usr.dig('status').to_i != 200 )
314
+ return {
315
+ 'status' => 404,
316
+ 'message' => format('User \'%s\' not found', login_or_email)
317
+ }
318
+ end
319
+
320
+ org_id = org.dig('id')
321
+ usr_id = usr.dig('id')
322
+
323
+ endpoint = format( '/api/orgs/%d/users/%d', org_id, usr_id )
324
+
325
+ @logger.debug("Deleting user '#{login_or_email}' in organization '#{organization}' (DELETE #{endpoint})") if @debug
326
+ delete(endpoint)
327
+ end
328
+
329
+ # Create Organisation
330
+ #
331
+ # @param
332
+ # @option params [String] organization Organisation name
333
+ #
334
+ # @examle
335
+ # params = {
336
+ # name: 'Foo'
337
+ # }
338
+ # create_organisation( params )
339
+ #
340
+ # @return [Hash]
341
+ #
342
+ def create_organisation( params )
343
+
344
+ raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
345
+ raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
346
+
347
+ name = validate( params, required: true, var: 'name', type: String )
348
+
349
+ org = organization( name )
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
357
+
358
+ endpoint = '/api/orgs'
359
+ payload = {
360
+ name: name
361
+ }
362
+ @logger.debug("Create Organisation (POST #{endpoint})") if @debug
363
+
364
+ post( endpoint, payload.to_json )
365
+ end
366
+
367
+ # Delete Organisation
368
+ #
369
+ # @param [Mixed] organisation_id Organisation Name (String) or Organisation Id (Integer) for delete Organisation
370
+ #
371
+ # @example
372
+ # delete_organisation( 1 )
373
+ # delete_organisation( 'Foo' )
374
+ #
375
+ # @return [Hash]
376
+ #
377
+ def delete_organisation( organisation_id )
378
+
379
+ raise ArgumentError.new(format('wrong type. user \'organisation_id\' must be an String (for an Datasource name) or an Integer (for an Datasource Id), given \'%s\'', organisation_id.class.to_s)) if( organisation_id.is_a?(String) && organisation_id.is_a?(Integer) )
380
+ raise ArgumentError.new('missing \'organisation_id\'') if( organisation_id.size.zero? )
381
+
382
+ if(organisation_id.is_a?(String))
383
+ data = organizations.dig('message')
384
+ organisation_map = {}
385
+ data.each do |ds|
386
+ organisation_map[ds['id']] = ds
387
+ end
388
+ organisation_map.select { |_k,v| v['name'] == organisation_id }
389
+ organisation_id = organisation_map.keys.first if( data )
390
+ end
391
+
392
+ if( organisation_id.nil? )
393
+ return {
394
+ 'status' => 404,
395
+ 'message' => format( 'No Organisation \'%s\' found', organisation_id)
396
+ }
397
+ end
398
+
399
+ endpoint = format( '/api/orgs/%d', organisation_id )
400
+ @logger.debug("Deleting organization #{organisation_id} (DELETE #{endpoint})") if @debug
401
+
402
+ delete(endpoint)
403
+ end
404
+
405
+ end
406
+ end