grafana-api 0.0.1 → 0.1.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 +4 -4
- data/lib/grafana.rb +2 -0
- data/lib/grafana/admin.rb +70 -0
- data/lib/grafana/client.rb +100 -0
- data/lib/grafana/dashboard.rb +60 -0
- data/lib/grafana/dashboard_template.rb +224 -0
- data/lib/grafana/datasource.rb +64 -0
- data/lib/grafana/frontend.rb +13 -0
- data/lib/grafana/http_request.rb +66 -0
- data/lib/grafana/login.rb +13 -0
- data/lib/grafana/organization.rb +33 -0
- data/lib/grafana/organizations.rb +46 -0
- data/lib/grafana/snapshot.rb +25 -0
- data/lib/grafana/user.rb +44 -0
- data/lib/grafana/users.rb +51 -0
- data/lib/grafana/version.rb +3 -0
- metadata +25 -11
- data/lib/grafana-api.rb +0 -355
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eb679815babc5bcb0c1f9aaae398ad9a0db96528
|
|
4
|
+
data.tar.gz: 448445928c252bbef2fcad51150b1c4df111fbb2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8e51435dfa74cdbc8e0a9d89a70415a37076c6e04d4dd44c645f0c549d401418b04180227afdceede958509403925a884e24548b9a6a7a306a325c072cda94ae
|
|
7
|
+
data.tar.gz: e6ee4a7fea2f7be1d8cf6be2d2261c439995a5aafc07dc1ffe5937c2845892b87ec01c4433a01d023fa50e603e74f77ae3075456050847cc478e8cf98862eaab
|
data/lib/grafana.rb
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
|
|
2
|
+
module Grafana
|
|
3
|
+
|
|
4
|
+
module Admin
|
|
5
|
+
|
|
6
|
+
def get_admin_settings()
|
|
7
|
+
endpoint = "/api/admin/settings"
|
|
8
|
+
@logger.info("Getting admin settings (GET #{endpoint})") if @debug
|
|
9
|
+
return get_request(endpoint)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def update_user_permissions(id, perm)
|
|
13
|
+
|
|
14
|
+
valid_perms = ['Viewer','Editor','Read Only Editor','Admin']
|
|
15
|
+
|
|
16
|
+
if perm.class.to_s == "String" && !valid_perms.include?(perm)
|
|
17
|
+
@logger.warn("Basic user permissions include: #{valid_perms.join(',')}") if @debug
|
|
18
|
+
return false
|
|
19
|
+
elsif perm.class.to_s == "Hash" &&
|
|
20
|
+
( !perm.has_key?('isGrafanaAdmin') || ![true,false].include?(perm['isGrafanaAdmin']) )
|
|
21
|
+
@logger.warn("Grafana admin permission must be either true or false") if @debug
|
|
22
|
+
return false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
@logger.info("Updating user ID #{id} permissions") if @debug
|
|
26
|
+
|
|
27
|
+
if perm.class.to_s == 'Hash'
|
|
28
|
+
endpoint = "/api/admin/users/#{id}/permissions"
|
|
29
|
+
@logger.info("Updating user ID #{id} permissions (PUT #{endpoint})") if @debug
|
|
30
|
+
return put_request(endpoint, {"isGrafanaAdmin" => perm['isGrafanaAdmin']}.to_json)
|
|
31
|
+
else
|
|
32
|
+
org = self.get_current_org()
|
|
33
|
+
endpoint = "/api/orgs/#{org['id']}/users/#{id}"
|
|
34
|
+
@logger.info("Updating user ID #{id} permissions (PUT #{endpoint})") if @debug
|
|
35
|
+
user = {
|
|
36
|
+
'name' => org['name'],
|
|
37
|
+
'orgId' => org['id'],
|
|
38
|
+
'role' => perm.downcase.capitalize
|
|
39
|
+
}
|
|
40
|
+
return patch_request(endpoint, user.to_json)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def delete_user(user_id)
|
|
45
|
+
if user_id == 1
|
|
46
|
+
@logger.warn("Can't delete user ID #{user_id} (admin user)") if @debug
|
|
47
|
+
return false
|
|
48
|
+
end
|
|
49
|
+
endpoint = "/api/admin/users/#{user_id}"
|
|
50
|
+
@logger.info("Deleting user ID #{user_id} (DELETE #{endpoint})") if @debug
|
|
51
|
+
return delete_request(endpoint)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def create_user(properties={})
|
|
55
|
+
endpoint = "/api/admin/users"
|
|
56
|
+
@logger.info("Creating user: #{properties['name']}") if @debug
|
|
57
|
+
@logger.info("Data: #{properties.to_s}") if @debug
|
|
58
|
+
return post_request(endpoint, properties.to_json)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def update_user_pass(user_id,password)
|
|
62
|
+
endpoint = " /api/admin/users/#{user_id}/#{password}"
|
|
63
|
+
@logger.info("Updating password for user ID #{user_id} (PUT #{endpoint})") if @debug
|
|
64
|
+
return put_request(endpoint,properties)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
|
|
2
|
+
require 'rest-client'
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'logger'
|
|
5
|
+
|
|
6
|
+
module Grafana
|
|
7
|
+
|
|
8
|
+
require_relative 'http_request'
|
|
9
|
+
require_relative 'user'
|
|
10
|
+
require_relative 'users'
|
|
11
|
+
require_relative 'datasource'
|
|
12
|
+
require_relative 'organization'
|
|
13
|
+
require_relative 'organizations'
|
|
14
|
+
require_relative 'dashboard'
|
|
15
|
+
require_relative 'dashboard_template'
|
|
16
|
+
require_relative 'snapshot'
|
|
17
|
+
require_relative 'frontend'
|
|
18
|
+
require_relative 'login'
|
|
19
|
+
require_relative 'admin'
|
|
20
|
+
require_relative 'version'
|
|
21
|
+
|
|
22
|
+
class Client
|
|
23
|
+
|
|
24
|
+
attr_reader :debug, :session_cookies, :headers, :logger, :api_instance
|
|
25
|
+
|
|
26
|
+
include Grafana::HttpRequest
|
|
27
|
+
include Grafana::User
|
|
28
|
+
include Grafana::Users
|
|
29
|
+
include Grafana::Datasource
|
|
30
|
+
include Grafana::Organization
|
|
31
|
+
include Grafana::Organizations
|
|
32
|
+
include Grafana::Dashboard
|
|
33
|
+
include Grafana::DashboardTemplate
|
|
34
|
+
include Grafana::Snapshot
|
|
35
|
+
include Grafana::Frontend
|
|
36
|
+
include Grafana::Login
|
|
37
|
+
include Grafana::Admin
|
|
38
|
+
|
|
39
|
+
def initialize(host="localhost", port=3000, user='admin', pass='', settings={})
|
|
40
|
+
|
|
41
|
+
if settings.has_key?('timeout') && settings['timeout'].to_i <= 0
|
|
42
|
+
settings['timeout'] = 5
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if settings.has_key?('open_timeout') && settings['open_timeout'].to_i <= 0
|
|
46
|
+
settings['open_timeout'] = 5
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if settings.has_key?('headers') && settings['headers'].class.to_s != 'Hash'
|
|
50
|
+
settings['headers'] = {}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
proto = ( settings.has_key?('ssl') && settings['ssl'] == true ? 'https' : 'http')
|
|
54
|
+
|
|
55
|
+
@logger.info("Initializing API client #{proto}://#{host}:#{port}") if @debug
|
|
56
|
+
@logger.info("Options: #{options}") if @debug
|
|
57
|
+
|
|
58
|
+
@api_instance = RestClient::Resource.new(
|
|
59
|
+
"#{proto}://#{host}:#{port}",
|
|
60
|
+
:timeout => settings['timeout'],
|
|
61
|
+
:open_timeout => settings['open_timeout'],
|
|
62
|
+
:headers => settings['headers']
|
|
63
|
+
)
|
|
64
|
+
@debug = (settings['debug'] ? true : false)
|
|
65
|
+
@logger = Logger.new(STDOUT)
|
|
66
|
+
@headers = nil
|
|
67
|
+
|
|
68
|
+
self.login(user, pass)
|
|
69
|
+
return self
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def login(user='admin',pass='admin')
|
|
73
|
+
@logger.info("Attempting to establish user session") if @debug
|
|
74
|
+
request_data = {'User' => user, 'Password' => pass}
|
|
75
|
+
begin
|
|
76
|
+
resp = @api_instance['/login'].post(
|
|
77
|
+
request_data.to_json,
|
|
78
|
+
{:content_type => 'application/json; charset=UTF-8'}
|
|
79
|
+
)
|
|
80
|
+
@session_cookies = resp.cookies
|
|
81
|
+
if resp.code.to_i == 200
|
|
82
|
+
@headers = {
|
|
83
|
+
:content_type => 'application/json; charset=UTF-8',
|
|
84
|
+
:cookies => @session_cookies
|
|
85
|
+
}
|
|
86
|
+
return true
|
|
87
|
+
else
|
|
88
|
+
return false
|
|
89
|
+
end
|
|
90
|
+
rescue => e
|
|
91
|
+
@logger.error("Error running POST request on /login: #{e}") if @debug
|
|
92
|
+
@logger.error("Request data: #{request_data.to_json}") if @debug
|
|
93
|
+
return false
|
|
94
|
+
end
|
|
95
|
+
@logger.info("User session initiated") if @debug
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end # End of Client class
|
|
99
|
+
|
|
100
|
+
end # End of GrafanaApi module
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
|
|
2
|
+
module Grafana
|
|
3
|
+
|
|
4
|
+
module Dashboard
|
|
5
|
+
|
|
6
|
+
def create_slug(text)
|
|
7
|
+
if text =~ /\s/
|
|
8
|
+
if text =~ /-/
|
|
9
|
+
text = text.gsub(/\s+/, "").downcase
|
|
10
|
+
else
|
|
11
|
+
text = text.gsub(/\s+/, "-").downcase
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
return text
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def get_dashboard(name='')
|
|
18
|
+
endpoint = "/api/dashboards/db/#{name}"
|
|
19
|
+
name = self.create_slug(name)
|
|
20
|
+
@logger.info("Attempting to get dashboard (GET /api/dashboards/db/#{name})") if @debug
|
|
21
|
+
return get_request(endpoint)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def create_dashboard(properties={})
|
|
25
|
+
endpoint = "/api/dashboards/db"
|
|
26
|
+
dashboard = self.build_template(properties)
|
|
27
|
+
@logger.info("Creating dashboard: #{properties['title']} (POST /api/dashboards/db)") if @debug
|
|
28
|
+
return post_request(endpoint, dashboard)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def delete_dashboard(name)
|
|
32
|
+
name = self.create_slug(name)
|
|
33
|
+
endpoint = "/api/dashboards/db/#{name}"
|
|
34
|
+
@logger.info("Deleting dahsboard ID #{id} (DELETE #{endpoint})") if @debug
|
|
35
|
+
return delete_request(endpoint)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def get_home_dashboard()
|
|
39
|
+
endpoint = "/api/dashboards/home"
|
|
40
|
+
@logger.info("Attempting to get home dashboard (GET #{endpoint})") if @debug
|
|
41
|
+
return get_request(endpoint)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def get_dashboard_tags()
|
|
45
|
+
endpoint = "/api/dashboards/tags"
|
|
46
|
+
@logger.info("Attempting to get dashboard tags(GET #{endpoint})") if @debug
|
|
47
|
+
return get_request(endpoint)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def search_dashboards(params={})
|
|
51
|
+
params['query'] = (params['query'].length >= 1 ? CGI::escape(params['query']) : '' )
|
|
52
|
+
params['starred'] = (params['starred'] ? 'true' : 'false')
|
|
53
|
+
endpoint = "/api/search/?query=#{params['query']}&starred=#{params['starred']}&tag=#{params['tags']}"
|
|
54
|
+
@logger.info("Attempting to search for dashboards (GET #{endpoint})") if @debug
|
|
55
|
+
return get_request(endpoint)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
|
|
2
|
+
module Grafana
|
|
3
|
+
|
|
4
|
+
module DashboardTemplate
|
|
5
|
+
|
|
6
|
+
# CloudWatch Namespaces, Dimensions and Metrics Reference:
|
|
7
|
+
# http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html
|
|
8
|
+
@@cw_dimensions = []
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def build_template(params={})
|
|
12
|
+
|
|
13
|
+
if !params.has_key?('from')
|
|
14
|
+
params['from'] = 'now-2h'
|
|
15
|
+
end
|
|
16
|
+
if !params.has_key?('to')
|
|
17
|
+
params['to'] = 'now'
|
|
18
|
+
end
|
|
19
|
+
if params['title'] == ''
|
|
20
|
+
return false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
rows = []
|
|
24
|
+
params['panels'].each do |panel|
|
|
25
|
+
rows.push(self.build_panel(panel))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
tpl = %q[
|
|
29
|
+
{
|
|
30
|
+
"dashboard": {
|
|
31
|
+
"id": null,
|
|
32
|
+
"title": "%{title}",
|
|
33
|
+
"originalTitle": "%{title}",
|
|
34
|
+
"annotations": {
|
|
35
|
+
"list": []
|
|
36
|
+
},
|
|
37
|
+
"hideControls": false,
|
|
38
|
+
"timezone": "browser",
|
|
39
|
+
"editable": true,
|
|
40
|
+
"rows": [
|
|
41
|
+
%{rows}
|
|
42
|
+
],
|
|
43
|
+
"time": {
|
|
44
|
+
"from": "%{from}",
|
|
45
|
+
"to": "%{to}"
|
|
46
|
+
},
|
|
47
|
+
"timepicker": {
|
|
48
|
+
"collapse": false,
|
|
49
|
+
"enable": true,
|
|
50
|
+
"notice": false,
|
|
51
|
+
"now": true,
|
|
52
|
+
"refresh_intervals": [
|
|
53
|
+
"5s",
|
|
54
|
+
"10s",
|
|
55
|
+
"30s",
|
|
56
|
+
"1m",
|
|
57
|
+
"5m",
|
|
58
|
+
"15m",
|
|
59
|
+
"30m",
|
|
60
|
+
"1h",
|
|
61
|
+
"2h",
|
|
62
|
+
"1d"
|
|
63
|
+
],
|
|
64
|
+
"status": "Stable",
|
|
65
|
+
"time_options": [
|
|
66
|
+
"5m",
|
|
67
|
+
"15m",
|
|
68
|
+
"1h",
|
|
69
|
+
"6h",
|
|
70
|
+
"12h",
|
|
71
|
+
"24h",
|
|
72
|
+
"2d",
|
|
73
|
+
"7d",
|
|
74
|
+
"30d"
|
|
75
|
+
],
|
|
76
|
+
"type": "timepicker"
|
|
77
|
+
},
|
|
78
|
+
"tags": ["api-templated"],
|
|
79
|
+
"templating": {
|
|
80
|
+
"list": []
|
|
81
|
+
},
|
|
82
|
+
"schemaVersion": 7,
|
|
83
|
+
"sharedCrosshair": false,
|
|
84
|
+
"style": "dark",
|
|
85
|
+
"version": 1,
|
|
86
|
+
"links": []
|
|
87
|
+
},
|
|
88
|
+
"overwrite": false
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
return tpl % {
|
|
93
|
+
title: params['title'],
|
|
94
|
+
from: params['from'],
|
|
95
|
+
to: params['to'],
|
|
96
|
+
rows: rows.join(',')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def build_panel(params={})
|
|
103
|
+
|
|
104
|
+
panel = %q[
|
|
105
|
+
{
|
|
106
|
+
"collapse": false,
|
|
107
|
+
"editable": true,
|
|
108
|
+
"height": "250px",
|
|
109
|
+
"panels": [
|
|
110
|
+
{
|
|
111
|
+
"aliasColors": {},
|
|
112
|
+
"bars": false,
|
|
113
|
+
"datasource": "%{datasource}",
|
|
114
|
+
"editable": true,
|
|
115
|
+
"error": false,
|
|
116
|
+
"fill": 1,
|
|
117
|
+
"grid": {
|
|
118
|
+
"leftLogBase": 1,
|
|
119
|
+
"leftMax": null,
|
|
120
|
+
"leftMin": null,
|
|
121
|
+
"rightLogBase": 1,
|
|
122
|
+
"rightMax": null,
|
|
123
|
+
"rightMin": null,
|
|
124
|
+
"threshold1": null,
|
|
125
|
+
"threshold1Color": "rgba(216, 200, 27, 0.27)",
|
|
126
|
+
"threshold2": null,
|
|
127
|
+
"threshold2Color": "rgba(234, 112, 112, 0.22)"
|
|
128
|
+
},
|
|
129
|
+
"legend": {
|
|
130
|
+
"avg": false,
|
|
131
|
+
"current": false,
|
|
132
|
+
"max": false,
|
|
133
|
+
"min": false,
|
|
134
|
+
"show": true,
|
|
135
|
+
"total": false,
|
|
136
|
+
"values": false
|
|
137
|
+
},
|
|
138
|
+
"lines": true,
|
|
139
|
+
"linewidth": 2,
|
|
140
|
+
"links": [],
|
|
141
|
+
"nullPointMode": "connected",
|
|
142
|
+
"percentage": false,
|
|
143
|
+
"pointradius": 5,
|
|
144
|
+
"points": false,
|
|
145
|
+
"renderer": "flot",
|
|
146
|
+
"seriesOverrides": [],
|
|
147
|
+
"span": 12,
|
|
148
|
+
"stack": false,
|
|
149
|
+
"steppedLine": false,
|
|
150
|
+
"targets": [
|
|
151
|
+
%{targets}
|
|
152
|
+
],
|
|
153
|
+
"timeFrom": null,
|
|
154
|
+
"timeShift": null,
|
|
155
|
+
"title": "%{graph_title}",
|
|
156
|
+
"tooltip": {
|
|
157
|
+
"shared": true,
|
|
158
|
+
"value_type": "cumulative"
|
|
159
|
+
},
|
|
160
|
+
"type": "graph",
|
|
161
|
+
"x-axis": true,
|
|
162
|
+
"y-axis": true,
|
|
163
|
+
"y_formats": [
|
|
164
|
+
"short",
|
|
165
|
+
"short"
|
|
166
|
+
]
|
|
167
|
+
}
|
|
168
|
+
],
|
|
169
|
+
"title": "Row"
|
|
170
|
+
}
|
|
171
|
+
]
|
|
172
|
+
|
|
173
|
+
targets = []
|
|
174
|
+
params['targets'].each do |t|
|
|
175
|
+
targets.push(self.build_target(t))
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
return panel % {
|
|
180
|
+
datasource: params['datasource'],
|
|
181
|
+
graph_title: params['graph_title'],
|
|
182
|
+
targets: targets.join(',')
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def build_target(params={})
|
|
190
|
+
|
|
191
|
+
target = %q[
|
|
192
|
+
{
|
|
193
|
+
"alias": "%{legend_alias}",
|
|
194
|
+
"dimensions": {
|
|
195
|
+
"%{dimension_name}": "%{dimension_value}"
|
|
196
|
+
},
|
|
197
|
+
"metricName": "%{metric_name}",
|
|
198
|
+
"namespace": "%{namespace}",
|
|
199
|
+
"period": 60,
|
|
200
|
+
"query": "",
|
|
201
|
+
"refId": "A",
|
|
202
|
+
"region": "%{region}",
|
|
203
|
+
"statistics": [
|
|
204
|
+
"Maximum"
|
|
205
|
+
],
|
|
206
|
+
"timeField": "@timestamp"
|
|
207
|
+
}
|
|
208
|
+
]
|
|
209
|
+
|
|
210
|
+
return target % {
|
|
211
|
+
metric_name: params['metric_name'],
|
|
212
|
+
namespace: params['namespace'],
|
|
213
|
+
dimension_name: params['dimension_name'],
|
|
214
|
+
dimension_value: params['dimension_value'],
|
|
215
|
+
region: params['region'],
|
|
216
|
+
legend_alias: params['legend_alias'],
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
end
|
|
224
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
|
|
2
|
+
module Grafana
|
|
3
|
+
|
|
4
|
+
module Datasource
|
|
5
|
+
|
|
6
|
+
def get_cw_namespaces(datasource_id)
|
|
7
|
+
endpoint = "/api/datasources/proxy/#{datasource_id}"
|
|
8
|
+
@logger.info("Getting data source namespaces (POST /api/datasources/proxy/#{datasource_id})") if @debug
|
|
9
|
+
return post_request(endpoint, {"action" => "__GetNamespaces"}.to_json)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def get_data_sources()
|
|
13
|
+
endpoint = "/api/datasources"
|
|
14
|
+
@logger.info("Attempting to get existing data sources (GET #{endpoint})") if @debug
|
|
15
|
+
data_sources = get_request(endpoint)
|
|
16
|
+
if !data_sources
|
|
17
|
+
return false
|
|
18
|
+
end
|
|
19
|
+
data_source_map = {}
|
|
20
|
+
data_sources.each { |ds|
|
|
21
|
+
data_source_map[ds['id']] = ds
|
|
22
|
+
}
|
|
23
|
+
return data_source_map
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def get_data_source(id)
|
|
27
|
+
endpoint = "/api/datasources/#{id}"
|
|
28
|
+
@logger.info("Attempting to get existing data source ID #{id}") if @debug
|
|
29
|
+
return get_request(endpoint)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def update_data_source(id, ds={})
|
|
33
|
+
existing_ds = self.get_data_source(id)
|
|
34
|
+
ds = existing_ds.merge(ds)
|
|
35
|
+
endpoint = "/api/datasources/#{id}"
|
|
36
|
+
@logger.info("Updating data source ID #{id}") if @debug
|
|
37
|
+
return put_request(endpoint, ds.to_json)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def create_data_source(ds={})
|
|
41
|
+
if ds == {} || !ds.has_key?('name') || !ds.has_key?('database')
|
|
42
|
+
@logger.error("Error: missing 'name' and 'database' values!") if @debug
|
|
43
|
+
return false
|
|
44
|
+
end
|
|
45
|
+
endpoint = "/api/datasources"
|
|
46
|
+
@logger.info("Creating data source: #{ds['name']} (database: #{ds['database']})") if @debug
|
|
47
|
+
return post_request(endpoint, ds.to_json)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def delete_data_source(id)
|
|
51
|
+
endpoint = "/api/datasources/#{id}"
|
|
52
|
+
@logger.info("Deleting data source #{id} (DELETE #{endpoint})") if @debug
|
|
53
|
+
return delete_request(endpoint)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def get_available_data_source_types()
|
|
57
|
+
endpoint = '/api/datasources/plugins'
|
|
58
|
+
@logger.info("Attempting to get existing data source types (GET #{endpoint})") if @debug
|
|
59
|
+
return get_request(endpoint)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module Grafana
|
|
2
|
+
|
|
3
|
+
module HttpRequest
|
|
4
|
+
|
|
5
|
+
def get_request(endpoint)
|
|
6
|
+
@logger.info("Running: Grafana::HttpRequest::#{__method__} on #{endpoint}") if @debug
|
|
7
|
+
return _issue_request('GET', endpoint)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def post_request(endpoint, postdata={})
|
|
11
|
+
@logger.info("Running: Grafana::HttpRequest::#{__method__} on #{endpoint}") if @debug
|
|
12
|
+
return _issue_request('POST', endpoint, postdata)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def put_request(endpoint, putdata={})
|
|
16
|
+
@logger.info("Running: Grafana::HttpRequest::#{__method__} on #{endpoint}") if @debug
|
|
17
|
+
return _issue_request('PUT', endpoint, putdata)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def delete_request(endpoint)
|
|
21
|
+
@logger.info("Running: Grafana::HttpRequest::#{__method__} on #{endpoint}") if @debug
|
|
22
|
+
return _issue_request('DELETE', endpoint)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def patch_request(endpoint, patchdata={})
|
|
26
|
+
@logger.info("Running: Grafana::HttpRequest::#{__method__} on #{endpoint}") if @debug
|
|
27
|
+
return _issue_request('PATCH', endpoint, patchdata)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def _issue_request(method_type='GET', endpoint='/', data={})
|
|
31
|
+
|
|
32
|
+
begin
|
|
33
|
+
resp = nil
|
|
34
|
+
case method_type.upcase
|
|
35
|
+
when 'GET'
|
|
36
|
+
resp = @api_instance[endpoint].get(@headers)
|
|
37
|
+
when 'POST'
|
|
38
|
+
resp = @api_instance[endpoint].patch(data,@headers)
|
|
39
|
+
when 'PATCH'
|
|
40
|
+
resp = @api_instance[endpoint].patch(data,@headers)
|
|
41
|
+
when 'PUT'
|
|
42
|
+
resp = @api_instance[endpoint].patch(data,@headers)
|
|
43
|
+
when 'DELETE'
|
|
44
|
+
resp = @api_instance[endpoint].patch(@headers)
|
|
45
|
+
else
|
|
46
|
+
@logger.error("Error: #{__method__} is not a valid request method.") if @debug
|
|
47
|
+
return false
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if (resp.code.to_i >= 200 && resp.code.to_i <= 299) || (resp.code.to_i >= 400 && resp.code.to_i <= 499)
|
|
51
|
+
return JSON.parse(resp.body)
|
|
52
|
+
else
|
|
53
|
+
@logger.error("#{__method__} on #{endpoint} failed: HTTP #{resp.code} - #{resp.body}") if @debug
|
|
54
|
+
return false
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
rescue => e
|
|
58
|
+
@logger.error("Error: #{__method__} #{endpoint} error: #{e}") if @debug
|
|
59
|
+
return false
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
|
|
2
|
+
module Grafana
|
|
3
|
+
|
|
4
|
+
module Organization
|
|
5
|
+
|
|
6
|
+
def get_current_org()
|
|
7
|
+
endpoint = "/api/org"
|
|
8
|
+
@logger.info("Getting current organization (GET #{endpoint})") if @debug
|
|
9
|
+
return get_request(endpoint)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def update_current_org(properties={})
|
|
13
|
+
endpoint = "/api/org"
|
|
14
|
+
@logger.info("Updating current organization (PUT #{endpoint})") if @debug
|
|
15
|
+
return put_request(endpoint, properties)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def get_current_org_users()
|
|
19
|
+
endpoint = "/api/org/users"
|
|
20
|
+
@logger.info("Getting organization users (GET #{endpoint})") if @debug
|
|
21
|
+
return get_request(endpoint)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def add_user_to_current_org(properties={})
|
|
25
|
+
endpoint = "/api/org/users"
|
|
26
|
+
@logger.info("Adding user to current organization (POST #{endpoint})") if @debug
|
|
27
|
+
return post_request(endpoint, properties)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
module Grafana
|
|
3
|
+
|
|
4
|
+
module Organizations
|
|
5
|
+
|
|
6
|
+
def get_all_orgs()
|
|
7
|
+
endpoint = "/api/orgs"
|
|
8
|
+
@logger.info("Getting all organizations (GET #{endpoint})") if @debug
|
|
9
|
+
return get_request(endpoint)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def update_org(org_id, properties={})
|
|
14
|
+
endpoint = "/api/orgs/#{org_id}"
|
|
15
|
+
@logger.info("Updating orgnaization ID #{org_id} (POST #{endpoint})") if @debug
|
|
16
|
+
return post_request(endpoint, properties)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def get_org_users(org_id)
|
|
20
|
+
endpoint = "/api/orgs/#{org_id}/users"
|
|
21
|
+
@logger.info("Getting users in orgnaization ID #{org_id} (GET #{endpoint})") if @debug
|
|
22
|
+
return get_request(endpoint)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def add_user_to_org(org_id, user={})
|
|
27
|
+
endpoint = "/api/orgs/#{org_id}/users"
|
|
28
|
+
@logger.info("Adding user to orgnaization ID #{org_id} (POST #{endpoint})") if @debug
|
|
29
|
+
return post_request(endpoint, user)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def update_org_user(org_id, user_id, properties={})
|
|
33
|
+
endpoint = "/api/orgs/#{org_id}/users/#{user_id}"
|
|
34
|
+
@logger.info("Updating user #{user_id} in organization #{org_id} (PATCH #{endpoint})") if @debug
|
|
35
|
+
return patch_request(endpoint, properties)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def delete_user_from_org(org_id, user_id)
|
|
39
|
+
endpoint = "/api/orgs/#{org_id}/users/#{user_id}"
|
|
40
|
+
@logger.info("Deleting user #{user_id} in organization #{org_id} (DELETE #{endpoint})") if @debug
|
|
41
|
+
return delete_request(endpoint)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Grafana
|
|
2
|
+
|
|
3
|
+
module Snapshot
|
|
4
|
+
|
|
5
|
+
def get_snapshot(key)
|
|
6
|
+
endpoint = "/api/snapshot/#{key}"
|
|
7
|
+
@logger.info("Getting frontend settings (GET #{endpoint})") if @debug
|
|
8
|
+
return get_request(endpoint)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def create_snapshot(dashboard={})
|
|
12
|
+
endpoint = "/api/snapshot"
|
|
13
|
+
@logger.info("Creating dashboard snapshot (POST #{endpoint})") if @debug
|
|
14
|
+
return post_request(endpoint, dashboard)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def delete_snapshot(key)
|
|
18
|
+
endpoint = "/api/snapshots-delete/#{key}"
|
|
19
|
+
@logger.info("Deleting snapshot ID #{key} (GET #{endpoint})") if @debug
|
|
20
|
+
return delete_request(endpoint)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
data/lib/grafana/user.rb
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
|
|
2
|
+
module Grafana
|
|
3
|
+
|
|
4
|
+
module User
|
|
5
|
+
|
|
6
|
+
def get_current_user()
|
|
7
|
+
endpoint = "/api/user"
|
|
8
|
+
@logger.info("Getting user current user (GET #{endpoint})") if @debug
|
|
9
|
+
return get_request(endpoint)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def update_current_user_pass(properties={})
|
|
13
|
+
endpoint = "/api/user/password"
|
|
14
|
+
@logger.info("Updating current user password (PUT #{endpoint})") if @debug
|
|
15
|
+
return put_request(endpoint,properties)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def switch_current_user_org(org_id)
|
|
19
|
+
endpoint = "/api/user/using/#{org_id}"
|
|
20
|
+
@logger.info("Switching current user to Org ID #{id} (GET #{endpoint})") if @debug
|
|
21
|
+
return post_request(endpoint, {})
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def get_current_user_orgs()
|
|
25
|
+
endpoint = "/api/user/orgs"
|
|
26
|
+
@logger.info("Getting current user organizations (GET #{endpoint})") if @debug
|
|
27
|
+
return get_request(endpoint)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def add_dashboard_star(dashboard_id)
|
|
31
|
+
endpoint = "/api/user/stars/dashboard/#{dashboard_id}"
|
|
32
|
+
@logger.info("Adding start to dashboard ID #{dashboard_id} (GET #{endpoint})") if @debug
|
|
33
|
+
return post_request(endpoint, {})
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def remove_dashboard_star(dashboard_id)
|
|
37
|
+
endpoint = "/api/user/stars/dashboard/#{dashboard_id}"
|
|
38
|
+
@logger.info("Deleting start on dashboard ID #{dashboard_id} (GET #{endpoint})") if @debug
|
|
39
|
+
return delete_request(endpoint)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
|
|
2
|
+
module Grafana
|
|
3
|
+
|
|
4
|
+
module Users
|
|
5
|
+
|
|
6
|
+
def get_all_users()
|
|
7
|
+
endpoint = "/api/users"
|
|
8
|
+
@logger.info("Getting all users (GET #{endpoint})") if @debug
|
|
9
|
+
return get_request(endpoint)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def get_user_by_id(id)
|
|
13
|
+
endpoint = "/api/users/#{id}"
|
|
14
|
+
@logger.info("Getting user ID #{id} (GET #{endpoint})") if @debug
|
|
15
|
+
return get_request(endpoint)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def search_for_users_by(search={})
|
|
19
|
+
all_users = self.get_all_users()
|
|
20
|
+
key, value = search.first
|
|
21
|
+
@logger.info("Searching for users matching #{key} = #{value}") if @debug
|
|
22
|
+
users = []
|
|
23
|
+
all_users.each do |u|
|
|
24
|
+
if u[key] && u[key] == value
|
|
25
|
+
users.push(u)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
return (users.length >= 1 ? users : false)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def update_user_info(id, properties={})
|
|
32
|
+
endpoint = "/api/users/#{id}"
|
|
33
|
+
@logger.info("Updating user ID #{id}") if @debug
|
|
34
|
+
existing_user = self.get_user(id)
|
|
35
|
+
if !existing_user
|
|
36
|
+
@logger.error("User #{id} does not exist") if @debug
|
|
37
|
+
return false
|
|
38
|
+
end
|
|
39
|
+
properties = existing_user.merge(properties)
|
|
40
|
+
return put_request(endpoint,properties.to_json)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def get_user_orgs(userid)
|
|
44
|
+
endpoint = "/api/users/#{userid}/orgs"
|
|
45
|
+
@logger.info("Getting organizations for user #{id} (GET #{endpoint})") if @debug
|
|
46
|
+
return get_request(endpoint)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
metadata
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: grafana-api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alain Lefebvre
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-11
|
|
11
|
+
date: 2015-12-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: json
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - ~>
|
|
17
|
+
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '1.7'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- - ~>
|
|
24
|
+
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '1.7'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rest-client
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - ~>
|
|
31
|
+
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: '1.8'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- - ~>
|
|
38
|
+
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '1.8'
|
|
41
41
|
description: A simple wrapper for the Grafana HTTP API
|
|
@@ -44,7 +44,21 @@ executables: []
|
|
|
44
44
|
extensions: []
|
|
45
45
|
extra_rdoc_files: []
|
|
46
46
|
files:
|
|
47
|
-
- lib/grafana
|
|
47
|
+
- lib/grafana.rb
|
|
48
|
+
- lib/grafana/admin.rb
|
|
49
|
+
- lib/grafana/client.rb
|
|
50
|
+
- lib/grafana/dashboard.rb
|
|
51
|
+
- lib/grafana/dashboard_template.rb
|
|
52
|
+
- lib/grafana/datasource.rb
|
|
53
|
+
- lib/grafana/frontend.rb
|
|
54
|
+
- lib/grafana/http_request.rb
|
|
55
|
+
- lib/grafana/login.rb
|
|
56
|
+
- lib/grafana/organization.rb
|
|
57
|
+
- lib/grafana/organizations.rb
|
|
58
|
+
- lib/grafana/snapshot.rb
|
|
59
|
+
- lib/grafana/user.rb
|
|
60
|
+
- lib/grafana/users.rb
|
|
61
|
+
- lib/grafana/version.rb
|
|
48
62
|
homepage: http://github.com/lightspeedretail/ruby-grafana-api
|
|
49
63
|
licenses:
|
|
50
64
|
- MIT
|
|
@@ -55,18 +69,18 @@ require_paths:
|
|
|
55
69
|
- lib
|
|
56
70
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
57
71
|
requirements:
|
|
58
|
-
- -
|
|
72
|
+
- - ">="
|
|
59
73
|
- !ruby/object:Gem::Version
|
|
60
74
|
version: '0'
|
|
61
75
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
62
76
|
requirements:
|
|
63
|
-
- -
|
|
77
|
+
- - ">="
|
|
64
78
|
- !ruby/object:Gem::Version
|
|
65
79
|
version: '0'
|
|
66
80
|
requirements: []
|
|
67
81
|
rubyforge_project:
|
|
68
|
-
rubygems_version: 2.
|
|
82
|
+
rubygems_version: 2.4.6
|
|
69
83
|
signing_key:
|
|
70
84
|
specification_version: 4
|
|
71
|
-
summary: Grafana API Wrapper
|
|
85
|
+
summary: Grafana HTTP API Wrapper
|
|
72
86
|
test_files: []
|
data/lib/grafana-api.rb
DELETED
|
@@ -1,355 +0,0 @@
|
|
|
1
|
-
class GrafanaApi
|
|
2
|
-
|
|
3
|
-
require 'rest-client'
|
|
4
|
-
require 'json'
|
|
5
|
-
require 'logger'
|
|
6
|
-
|
|
7
|
-
attr_accessor :debug, :session_cookies, :headers
|
|
8
|
-
|
|
9
|
-
def initialize(host="localhost", port=3000, debug=false)
|
|
10
|
-
@api_instance = RestClient::Resource.new("http://#{host}:#{port}")
|
|
11
|
-
@debug = debug
|
|
12
|
-
@logger = Logger.new(STDOUT)
|
|
13
|
-
@headers = nil
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def login(user='admin',pass='admin')
|
|
17
|
-
@logger.info("Attempting to establish user session") if @debug
|
|
18
|
-
request_data = {'User' => user, 'Password' => pass}
|
|
19
|
-
begin
|
|
20
|
-
resp = @api_instance['/login'].post(
|
|
21
|
-
request_data.to_json,
|
|
22
|
-
{:content_type => 'application/json; charset=UTF-8'}
|
|
23
|
-
)
|
|
24
|
-
@session_cookies = resp.cookies
|
|
25
|
-
if resp.code.to_i == 200
|
|
26
|
-
@headers = {
|
|
27
|
-
:content_type => 'application/json; charset=UTF-8',
|
|
28
|
-
:cookies => @session_cookies
|
|
29
|
-
}
|
|
30
|
-
return true
|
|
31
|
-
else
|
|
32
|
-
return false
|
|
33
|
-
end
|
|
34
|
-
rescue => e
|
|
35
|
-
@logger.error("Error running POST request on /login: #{e}") if @debug
|
|
36
|
-
@logger.error("Request data: #{request_data.to_json}") if @debug
|
|
37
|
-
return false
|
|
38
|
-
end
|
|
39
|
-
@logger.info("User session initiated") if @debug
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def get_user(id)
|
|
45
|
-
@logger.info("Getting user ID #{id} (GET /api/users/#{id})") if @debug
|
|
46
|
-
begin
|
|
47
|
-
resp = @api_instance["/api/users/#{id}"].get(@headers)
|
|
48
|
-
if resp.code.to_i == 200
|
|
49
|
-
return JSON.parse(resp.body)
|
|
50
|
-
else
|
|
51
|
-
@logger.error("Could not get user: #{resp.body}") if @debug
|
|
52
|
-
return false
|
|
53
|
-
end
|
|
54
|
-
rescue => e
|
|
55
|
-
@logger.error("Could not get user: #{e}") if @debug
|
|
56
|
-
return false
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def get_users()
|
|
61
|
-
@logger.info("Getting all users (GET /api/users)") if @debug
|
|
62
|
-
begin
|
|
63
|
-
resp = @api_instance['/api/users'].get(@headers)
|
|
64
|
-
if resp.code.to_i == 200
|
|
65
|
-
return JSON.parse(resp.body)
|
|
66
|
-
else
|
|
67
|
-
@logger.error("Could not get list of users: #{resp.body}") if @debug
|
|
68
|
-
return false
|
|
69
|
-
end
|
|
70
|
-
rescue => e
|
|
71
|
-
@logger.error("Could not get list of users: #{e}") if @debug
|
|
72
|
-
return false
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def search_for_users_by(search={})
|
|
77
|
-
all_users = self.get_users()
|
|
78
|
-
key, value = search.first
|
|
79
|
-
@logger.info("Searching for users matching #{key} = #{value}") if @debug
|
|
80
|
-
users = []
|
|
81
|
-
all_users.each do |u|
|
|
82
|
-
if u[key] && u[key] == value
|
|
83
|
-
users.push(u)
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
return (users.length >= 1 ? users : false)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def create_user(properties={})
|
|
90
|
-
@logger.info("Creating user: #{properties['name']}") if @debug
|
|
91
|
-
@logger.info("Data: #{properties.to_s}") if @debug
|
|
92
|
-
begin
|
|
93
|
-
resp = @api_instance["/api/admin/users"].post(
|
|
94
|
-
properties.to_json,
|
|
95
|
-
@headers
|
|
96
|
-
)
|
|
97
|
-
result = JSON.parse(resp.body)
|
|
98
|
-
if resp.code.to_i == 200
|
|
99
|
-
@logger.info(resp.body) if @debug
|
|
100
|
-
return true
|
|
101
|
-
else
|
|
102
|
-
@logger.error("Data source could not be created: #{resp.body}") if @debug
|
|
103
|
-
return false
|
|
104
|
-
end
|
|
105
|
-
rescue => e
|
|
106
|
-
@logger.error("Error creating data source: #{e}") if @debug
|
|
107
|
-
return false
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def update_user_info(id, properties={})
|
|
112
|
-
@logger.info("Updating user ID #{id}") if @debug
|
|
113
|
-
begin
|
|
114
|
-
existing_user = self.get_user(id)
|
|
115
|
-
if !existing_user
|
|
116
|
-
@logger.error("User #{id} does not exist") if @debug
|
|
117
|
-
return false
|
|
118
|
-
end
|
|
119
|
-
properties = existing_user.merge(properties)
|
|
120
|
-
resp = @api_instance["/api/users/#{id}"].put(
|
|
121
|
-
properties.to_json,
|
|
122
|
-
@headers
|
|
123
|
-
)
|
|
124
|
-
if resp.code.to_i == 200
|
|
125
|
-
return JSON.parse(resp.body)
|
|
126
|
-
else
|
|
127
|
-
@logger.error("Could not update user (HTTP #{resp.code}: #{resp.body})") if @debug
|
|
128
|
-
return false
|
|
129
|
-
end
|
|
130
|
-
rescue => e
|
|
131
|
-
@logger.error("Could not update user: #{e}") if @debug
|
|
132
|
-
return false
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
def update_user_permissions(id, perm)
|
|
137
|
-
|
|
138
|
-
valid_perms = ['Viewer','Editor','Read Only Editor','Admin']
|
|
139
|
-
|
|
140
|
-
if perm.class.to_s == "String" &&
|
|
141
|
-
!valid_perms.include?(perm)
|
|
142
|
-
@logger.warn("Basic user permissions include: #{valid_perms.join(',')}") if @debug
|
|
143
|
-
return false
|
|
144
|
-
elsif perm.class.to_s == "Hash" &&
|
|
145
|
-
(!perm.has_key?('isGrafanaAdmin') ||
|
|
146
|
-
![true,false].include?(perm['isGrafanaAdmin']) )
|
|
147
|
-
@logger.warn("Grafana admin permission must be either true or false") if @debug
|
|
148
|
-
return false
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
@logger.info("Updating user ID #{id} permissions") if @debug
|
|
152
|
-
begin
|
|
153
|
-
if perm.class.to_s == 'Hash'
|
|
154
|
-
resp = @api_instance["/api/admin/users/#{id}/permissions"].put(
|
|
155
|
-
{"isGrafanaAdmin" => perm['isGrafanaAdmin']}.to_json,
|
|
156
|
-
@headers
|
|
157
|
-
)
|
|
158
|
-
else
|
|
159
|
-
org = self.get_current_org()
|
|
160
|
-
resp = @api_instance["/api/orgs/#{org['id']}/users/#{id}"].patch(
|
|
161
|
-
{ 'name' => org['name'], 'orgId' => org['id'],
|
|
162
|
-
'role' => perm.downcase.capitalize
|
|
163
|
-
}.to_json,
|
|
164
|
-
@headers
|
|
165
|
-
)
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
if resp.code.to_i == 200
|
|
169
|
-
@logger.error("User permissions have been updated: #{resp.body}") if @debug
|
|
170
|
-
return true
|
|
171
|
-
else
|
|
172
|
-
@logger.error("Could not update user permissions (HTTP #{resp.code}: #{resp.body})") if @debug
|
|
173
|
-
return false
|
|
174
|
-
end
|
|
175
|
-
rescue => e
|
|
176
|
-
@logger.error("Could not update user permissions: #{e}") if @debug
|
|
177
|
-
return false
|
|
178
|
-
end
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
def delete_user(id)
|
|
182
|
-
if id == 1
|
|
183
|
-
@logger.warn("Can't delete user ID #{id} (admin user)") if @debug
|
|
184
|
-
return false
|
|
185
|
-
end
|
|
186
|
-
@logger.info("Deleting user ID #{id} (DELETE /api/admin/users/#{id})") if @debug
|
|
187
|
-
begin
|
|
188
|
-
resp = @api_instance["/api/admin/users/#{id}"].delete(@headers)
|
|
189
|
-
if resp.code.to_i == 200
|
|
190
|
-
@logger.info("User ID #{id} has been deleted") if @debug
|
|
191
|
-
return true
|
|
192
|
-
else
|
|
193
|
-
@logger.error("Could note delete: #{resp.body}") if @debug
|
|
194
|
-
return false
|
|
195
|
-
end
|
|
196
|
-
rescue => e
|
|
197
|
-
@logger.error("Could not delete user: #{e}") if @debug
|
|
198
|
-
return false
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
def get_data_sources()
|
|
205
|
-
begin
|
|
206
|
-
@logger.info("Attempting to get existing data sources (GET /api/datasources)") if @debug
|
|
207
|
-
resp = @api_instance['/api/datasources'].get(@headers)
|
|
208
|
-
data_sources = JSON.parse(resp.body)
|
|
209
|
-
data_source_map = {}
|
|
210
|
-
data_sources.each { |ds|
|
|
211
|
-
data_source_map[ds['id']] = ds
|
|
212
|
-
}
|
|
213
|
-
if resp.code.to_i == 200
|
|
214
|
-
return data_source_map
|
|
215
|
-
else
|
|
216
|
-
@logger.error("Could not retreive data sources (HTTP #{resp.code}: #{resp.body})") if @debug
|
|
217
|
-
return false
|
|
218
|
-
end
|
|
219
|
-
rescue => e
|
|
220
|
-
@logger.error("Error getting existing data sources: #{e}") if @debug
|
|
221
|
-
return false
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
def get_data_source(id)
|
|
226
|
-
begin
|
|
227
|
-
@logger.info("Attempting to get existing data source ID #{id}") if @debug
|
|
228
|
-
resp = @api_instance["/api/datasources/#{id}"].get(@headers)
|
|
229
|
-
if resp.code.to_i == 200
|
|
230
|
-
return JSON.parse(resp.body)
|
|
231
|
-
else
|
|
232
|
-
@logger.error("Could not get data source (HTTP #{resp.code}: #{resp.body})") if @debug
|
|
233
|
-
return false
|
|
234
|
-
end
|
|
235
|
-
rescue => e
|
|
236
|
-
@logger.error("Error getting existing data sources: #{e}") if @debug
|
|
237
|
-
return false
|
|
238
|
-
end
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
def update_data_source(id, ds={})
|
|
242
|
-
@logger.info("Updating data source ID #{id}") if @debug
|
|
243
|
-
|
|
244
|
-
existing_ds = self.get_data_source(id)
|
|
245
|
-
ds = existing_ds.merge(ds)
|
|
246
|
-
@logger.info(ds)
|
|
247
|
-
|
|
248
|
-
begin
|
|
249
|
-
resp = @api_instance["/api/datasources/#{id}"].put(
|
|
250
|
-
ds.to_json,
|
|
251
|
-
@headers
|
|
252
|
-
)
|
|
253
|
-
if resp.code.to_i == 200
|
|
254
|
-
@logger.info("Data source successfully updated") if @debug
|
|
255
|
-
return true
|
|
256
|
-
else
|
|
257
|
-
@logger.info("Data source could not be updated (HTTP #{resp.code}: #{resp.body})") if @debug
|
|
258
|
-
return false
|
|
259
|
-
end
|
|
260
|
-
rescue => e
|
|
261
|
-
@logger.error("Error updating data source: #{e}") if @debug
|
|
262
|
-
return false
|
|
263
|
-
end
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
def create_data_source(ds={})
|
|
267
|
-
@logger.info("Creating data source: #{ds['name']} (database: #{ds['database']})") if @debug
|
|
268
|
-
begin
|
|
269
|
-
resp = @api_instance["/api/datasources"].post(
|
|
270
|
-
ds.to_json,
|
|
271
|
-
@headers
|
|
272
|
-
)
|
|
273
|
-
result = JSON.parse(resp.body)
|
|
274
|
-
if resp.code.to_i == 200
|
|
275
|
-
@logger.info("Data source ID #{result['id']} has been created") if @debug
|
|
276
|
-
return true
|
|
277
|
-
else
|
|
278
|
-
@logger.error("Data source could not be created (HTTP #{resp.code}: #{resp.body})") if @debug
|
|
279
|
-
return false
|
|
280
|
-
end
|
|
281
|
-
rescue => e
|
|
282
|
-
@logger.error("Error creating data source: #{e}") if @debug
|
|
283
|
-
return false
|
|
284
|
-
end
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
def delete_data_source(id)
|
|
288
|
-
@logger.info("Deleting data source #{id}") if @debug
|
|
289
|
-
begin
|
|
290
|
-
resp = @api_instance["/api/datasources/#{id}"].delete(@headers)
|
|
291
|
-
result = JSON.parse(resp.body)
|
|
292
|
-
if resp.code.to_i == 200
|
|
293
|
-
@logger.info("Data source ID #{id} has been deleted") if @debug
|
|
294
|
-
return true
|
|
295
|
-
else
|
|
296
|
-
@logger.error("Data source could not be deleted (HTTP #{resp.code}): #{resp.body}") if @debug
|
|
297
|
-
return false
|
|
298
|
-
end
|
|
299
|
-
rescue => e
|
|
300
|
-
@logger.error("Error creating data source: #{e}") if @debug
|
|
301
|
-
return false
|
|
302
|
-
end
|
|
303
|
-
end
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
def get_current_org()
|
|
308
|
-
@logger.info("Getting current organization (GET /api/org)") if @debug
|
|
309
|
-
begin
|
|
310
|
-
resp = @api_instance['/api/org'].get(@headers)
|
|
311
|
-
if resp.code.to_i == 200
|
|
312
|
-
return JSON.parse(resp.body)
|
|
313
|
-
else
|
|
314
|
-
@logger.error("Could not get current organization: #{resp.body}") if @debug
|
|
315
|
-
return false
|
|
316
|
-
end
|
|
317
|
-
rescue => e
|
|
318
|
-
@logger.error("Could not get current organization: #{e}") if @debug
|
|
319
|
-
return false
|
|
320
|
-
end
|
|
321
|
-
end
|
|
322
|
-
|
|
323
|
-
def ping_session()
|
|
324
|
-
@logger.info("Pingning current session (GET /api/login/ping)") if @debug
|
|
325
|
-
begin
|
|
326
|
-
resp = @api_instance['/api/login/ping'].get(@headers)
|
|
327
|
-
if resp.code.to_i == 200
|
|
328
|
-
return true
|
|
329
|
-
else
|
|
330
|
-
@logger.error("Could not ping session: #{resp.body}") if @debug
|
|
331
|
-
return false
|
|
332
|
-
end
|
|
333
|
-
rescue => e
|
|
334
|
-
@logger.error("Could not ping session: #{e}") if @debug
|
|
335
|
-
return false
|
|
336
|
-
end
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
def get_admin_settings()
|
|
340
|
-
@logger.info("Getting admin settings (GET /api/admin/settings)") if @debug
|
|
341
|
-
begin
|
|
342
|
-
resp = @api_instance['/api/admin/settings'].get(@headers)
|
|
343
|
-
if resp.code.to_i == 200
|
|
344
|
-
return JSON.parse(resp.body)
|
|
345
|
-
else
|
|
346
|
-
@logger.error("Could not get admin settings: #{resp.body}") if @debug
|
|
347
|
-
return false
|
|
348
|
-
end
|
|
349
|
-
rescue => e
|
|
350
|
-
@logger.error("Could not get admin settings: #{e}") if @debug
|
|
351
|
-
return false
|
|
352
|
-
end
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
end
|