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/tools.rb
CHANGED
@@ -3,43 +3,67 @@ module Grafana
|
|
3
3
|
|
4
4
|
module Tools
|
5
5
|
|
6
|
+
# return a slugged string for Grafana Dashboards
|
7
|
+
#
|
8
|
+
# @param text [String] text
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# slug( 'test dashboard' )
|
12
|
+
#
|
13
|
+
# @retunr [String]
|
14
|
+
#
|
6
15
|
def slug( text )
|
7
16
|
|
8
17
|
raise ArgumentError.new(format('wrong type. \'text\' must be an String, given \'%s\'', text.class.to_s)) unless( text.is_a?(String) )
|
9
18
|
|
10
19
|
begin
|
11
|
-
|
20
|
+
if( text =~ /\s/ && text =~ /-/ )
|
12
21
|
# if( text =~ /-/ )
|
13
22
|
text = text.gsub( /\s+/, '' )
|
14
23
|
else
|
15
24
|
text = text.gsub( /\s+/, '-' )
|
16
25
|
# end
|
17
|
-
|
26
|
+
end
|
18
27
|
|
19
|
-
rescue =>
|
20
|
-
puts
|
28
|
+
rescue => error
|
29
|
+
puts error
|
21
30
|
end
|
22
31
|
|
23
32
|
text.downcase
|
24
33
|
end
|
25
34
|
|
26
|
-
|
35
|
+
# regenerate Row Ids in the Dashboard
|
36
|
+
# usefull for an automatic generated Dashboard
|
37
|
+
#
|
38
|
+
# @param params [Hash] params
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# params = {
|
42
|
+
# dashboard: {
|
43
|
+
# rows: [
|
44
|
+
#
|
45
|
+
# ]
|
46
|
+
# }
|
47
|
+
# }
|
48
|
+
# regenerate_template_ids( params )
|
49
|
+
#
|
50
|
+
# @return [Hash]
|
51
|
+
#
|
27
52
|
def regenerate_template_ids( params )
|
28
53
|
|
29
54
|
raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
|
55
|
+
raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
|
30
56
|
|
31
57
|
rows = params.dig('dashboard','rows')
|
58
|
+
# name = validate( params, required: true, var: 'name', type: String )
|
32
59
|
|
33
60
|
unless( rows.nil? )
|
34
61
|
|
35
62
|
# counter = 1
|
36
63
|
id_counter = 10
|
37
64
|
rows.each_with_index do |r, _counter|
|
38
|
-
|
39
65
|
panel = r.dig('panels')
|
40
|
-
|
41
66
|
next if( panel.nil? )
|
42
|
-
|
43
67
|
panel.each do |p|
|
44
68
|
p['id'] = id_counter
|
45
69
|
id_counter = id_counter +=1 # id_counter+1 # id_counter +=1 ??
|
@@ -50,17 +74,25 @@ module Grafana
|
|
50
74
|
JSON.generate( params )
|
51
75
|
end
|
52
76
|
|
53
|
-
|
77
|
+
# check, it an String a valid Json
|
78
|
+
#
|
79
|
+
# @param json [String] json
|
80
|
+
#
|
81
|
+
# @example
|
82
|
+
# valid_json?( json )
|
83
|
+
#
|
84
|
+
# @return [Boolean]
|
85
|
+
#
|
54
86
|
def valid_json?( json )
|
55
87
|
begin
|
56
88
|
JSON.parse( json )
|
57
89
|
return true
|
58
|
-
rescue JSON::ParserError =>
|
59
|
-
@logger.error("json parse error: #{
|
90
|
+
rescue JSON::ParserError => error
|
91
|
+
@logger.error("json parse error: #{error}") if @debug
|
60
92
|
return false
|
61
93
|
end
|
62
94
|
end
|
63
95
|
|
64
|
-
end
|
65
96
|
|
97
|
+
end
|
66
98
|
end
|
data/lib/grafana/user.rb
CHANGED
@@ -6,7 +6,12 @@ module Grafana
|
|
6
6
|
module User
|
7
7
|
|
8
8
|
# Actual User
|
9
|
-
#
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# current_user
|
12
|
+
#
|
13
|
+
# @return [Hash]
|
14
|
+
#
|
10
15
|
def current_user
|
11
16
|
endpoint = '/api/user'
|
12
17
|
@logger.debug("Getting user current user (GET #{endpoint})") if @debug
|
@@ -14,36 +19,51 @@ module Grafana
|
|
14
19
|
end
|
15
20
|
|
16
21
|
# Change Password
|
17
|
-
#
|
22
|
+
#
|
23
|
+
# @param [Hash] params
|
24
|
+
# @option params [String] old_password the old password
|
25
|
+
# @option params [String] new_password the new password
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
# update_current_user_password( old_password: 'foo', new_password: 'FooBar' )
|
29
|
+
#
|
30
|
+
# @return [Hash]
|
31
|
+
#
|
18
32
|
def update_current_user_password( params )
|
19
33
|
|
20
34
|
raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
|
35
|
+
raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
|
21
36
|
|
22
|
-
old_password
|
23
|
-
new_password
|
24
|
-
|
25
|
-
raise ArgumentError.new('missing old_password for update') if( old_password.nil? )
|
26
|
-
raise ArgumentError.new('missing new_password for update') if( new_password.nil? )
|
37
|
+
old_password = validate( params, required: true, var: 'old_password', type: String )
|
38
|
+
new_password = validate( params, required: true, var: 'new_password', type: String )
|
27
39
|
|
28
40
|
endpoint = '/api/user/password'
|
41
|
+
payload = {
|
42
|
+
oldPassword: old_password,
|
43
|
+
newPassword: new_password,
|
44
|
+
confirmNew: new_password
|
45
|
+
}
|
29
46
|
@logger.debug("Updating current user password (PUT #{endpoint})") if @debug
|
30
|
-
put( endpoint,
|
47
|
+
put( endpoint, payload.to_json )
|
31
48
|
end
|
32
49
|
|
33
50
|
# Switch user context for signed in user
|
34
|
-
#
|
51
|
+
#
|
52
|
+
# @param organization [String ] organization
|
53
|
+
#
|
54
|
+
# @example
|
55
|
+
# switch_current_user_organization( 'Main. Org' )
|
56
|
+
#
|
57
|
+
# @return [Hash]
|
58
|
+
#
|
35
59
|
def switch_current_user_organization( organization )
|
36
60
|
|
37
|
-
raise ArgumentError.new('organization must be an String') unless(
|
61
|
+
raise ArgumentError.new(format('wrong type. \'organization\' must be an String, given \'%s\'', organization.class.to_s)) unless( organization.is_a?(String) )
|
62
|
+
raise ArgumentError.new('missing \'organization\'') if( organization.size.zero? )
|
38
63
|
|
39
64
|
org = organization_by_name( organization )
|
40
65
|
|
41
|
-
if
|
42
|
-
return {
|
43
|
-
'status' => 404,
|
44
|
-
'message' => format('Organization \'%s\' not found', organization)
|
45
|
-
}
|
46
|
-
end
|
66
|
+
return { 'status' => 404, 'message' => format('Organization \'%s\' not found', organization) } if( org.nil? || org.dig('status').to_i != 200 )
|
47
67
|
|
48
68
|
org_id = org.dig('id')
|
49
69
|
|
@@ -54,52 +74,71 @@ module Grafana
|
|
54
74
|
end
|
55
75
|
|
56
76
|
# Organisations of the actual User
|
57
|
-
#
|
77
|
+
#
|
78
|
+
# @example
|
79
|
+
# current_user_oganizations
|
80
|
+
#
|
81
|
+
# @return [Hash]
|
82
|
+
#
|
58
83
|
def current_user_oganizations
|
59
|
-
|
60
84
|
endpoint = '/api/user/orgs'
|
61
85
|
@logger.debug("Getting current user organizations (GET #{endpoint})") if @debug
|
62
86
|
get(endpoint)
|
63
87
|
end
|
64
88
|
|
65
89
|
# Star a dashboard
|
66
|
-
#
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
90
|
+
#
|
91
|
+
# @param [Mixed] dashboard_id Dashboard Name (String) or Dashboard Id (Integer) for add a star
|
92
|
+
#
|
93
|
+
# @example
|
94
|
+
# add_dashboard_star( 1 )
|
95
|
+
# add_dashboard_star( 'QA Graphite Carbon Metrics' )
|
96
|
+
#
|
97
|
+
# @return [Hash]
|
98
|
+
#
|
99
|
+
def add_dashboard_star( dashboard_id )
|
100
|
+
|
101
|
+
if( dashboard_id.is_a?(String) && dashboard_id.is_a?(Integer) )
|
102
|
+
raise ArgumentError.new(format('wrong type. \'dashboard_id\' must be an String (for an Dashboard name) or an Integer (for an Dashboard Id), given \'%s\'', dashboard_id.class.to_s))
|
71
103
|
end
|
104
|
+
raise ArgumentError.new('missing \'dashboard_id\'') if( dashboard_id.size.zero? )
|
72
105
|
|
73
|
-
dashboard_id = dashboard if(
|
106
|
+
dashboard_id = dashboard if(dashboard_id.is_a?(Integer))
|
74
107
|
|
75
|
-
if(
|
76
|
-
|
77
|
-
r = search_dashboards( search )
|
108
|
+
if(dashboard_id.is_a?(String))
|
109
|
+
r = search_dashboards( query: dashboard_id )
|
78
110
|
message = r.dig('message')
|
79
111
|
dashboard_id = message.first.dig('id')
|
80
112
|
end
|
81
113
|
|
82
|
-
raise format('Dashboard
|
114
|
+
raise format('Dashboard Id can not be 0') if( dashboard_id.zero? )
|
83
115
|
|
84
116
|
endpoint = format( '/api/user/stars/dashboard/%d', dashboard_id )
|
85
117
|
@logger.debug("Adding star to dashboard id #{dashboard_id} (GET #{endpoint})") if @debug
|
86
|
-
post(endpoint, {}.to_json)
|
118
|
+
post( endpoint, {}.to_json )
|
87
119
|
end
|
88
120
|
|
89
121
|
# Unstar a dashboard
|
90
|
-
#
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
122
|
+
#
|
123
|
+
# @param [Mixed] dashboard_id Dashboard Name (String) or Dashboard Id (Integer) for delete a star
|
124
|
+
#
|
125
|
+
# @example
|
126
|
+
# remove_dashboard_star( 1 )
|
127
|
+
# remove_dashboard_star( 'QA Graphite Carbon Metrics' )
|
128
|
+
#
|
129
|
+
# @return [Hash]
|
130
|
+
#
|
131
|
+
def remove_dashboard_star( dashboard_id )
|
132
|
+
|
133
|
+
if( dashboard_id.is_a?(String) && dashboard_id.is_a?(Integer) )
|
134
|
+
raise ArgumentError.new(format('wrong type. \'dashboard_id\' must be an String (for an Dashboard name) or an Integer (for an Dashboard Id), given \'%s\'', dashboard_id.class.to_s))
|
95
135
|
end
|
136
|
+
raise ArgumentError.new('missing \'dashboard_id\'') if( dashboard_id.size.zero? )
|
96
137
|
|
97
|
-
dashboard_id = dashboard if(
|
98
|
-
|
99
|
-
if(dashboard.is_a?(String))
|
138
|
+
dashboard_id = dashboard( dashboard_id ) if(dashboard_id.is_a?(Integer))
|
100
139
|
|
101
|
-
|
102
|
-
r = search_dashboards(
|
140
|
+
if(dashboard_id.is_a?(String))
|
141
|
+
r = search_dashboards( query: dashboard_id )
|
103
142
|
message = r.dig('message')
|
104
143
|
dashboard_id = message.first.dig('id')
|
105
144
|
end
|
data/lib/grafana/users.rb
CHANGED
@@ -5,113 +5,164 @@ module Grafana
|
|
5
5
|
#
|
6
6
|
module Users
|
7
7
|
|
8
|
-
#
|
9
|
-
#
|
10
|
-
|
8
|
+
# All Users
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# all_users
|
12
|
+
#
|
13
|
+
# @return [Hash]
|
14
|
+
#
|
15
|
+
def users
|
11
16
|
endpoint = '/api/users'
|
12
17
|
@logger.debug("Getting all users (GET #{endpoint})") if @debug
|
13
18
|
get(endpoint)
|
14
19
|
end
|
15
20
|
|
16
|
-
# Get single user by Id
|
17
|
-
#
|
18
|
-
|
21
|
+
# Get a single user by Id or Name
|
22
|
+
#
|
23
|
+
# @param [Mixed] user_id Username (String) or Userid (Integer)
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# user( 1 )
|
27
|
+
# user( 'foo' )
|
28
|
+
#
|
29
|
+
# @return [Hash]
|
30
|
+
#
|
31
|
+
def user( user_id )
|
32
|
+
|
33
|
+
if( user_id.is_a?(String) && user_id.is_a?(Integer) )
|
34
|
+
raise ArgumentError.new(format('wrong type. user \'user_id\' must be an String (for an User name) or an Integer (for an User Id), given \'%s\'', user_id.class.to_s))
|
35
|
+
end
|
36
|
+
raise ArgumentError.new('missing \'user_id\'') if( user_id.size.zero? )
|
19
37
|
|
20
|
-
|
38
|
+
if(user_id.is_a?(String))
|
39
|
+
usrs = users
|
40
|
+
usrs = JSON.parse(usrs) if(usrs.is_a?(String))
|
21
41
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
42
|
+
status = usrs.dig('status')
|
43
|
+
return usrs if( status != 200 )
|
44
|
+
|
45
|
+
u = usrs.dig('message').detect { |v| v['login'] == user_id || v['email'] == user_id || v['name'] == user_id }
|
46
|
+
|
47
|
+
return { 'status' => 404, 'message' => format( 'No User \'%s\' found', user_id) } if( u.nil? )
|
48
|
+
|
49
|
+
user_id = u.dig('id') unless(u.nil?)
|
50
|
+
end
|
51
|
+
|
52
|
+
return { 'status' => 404, 'message' => format( 'No User \'%s\' found', user_id) } if( user_id.nil? )
|
26
53
|
|
27
|
-
|
28
|
-
# GET /api/users/lookup?loginOrEmail=user@mygraf.com
|
29
|
-
def user_by_name( name )
|
54
|
+
endpoint = format( '/api/users/%s', user_id )
|
30
55
|
|
31
|
-
|
32
|
-
|
33
|
-
|
56
|
+
@logger.debug("Getting user by Id #{user_id} (GET #{endpoint})") if @debug
|
57
|
+
data = get(endpoint)
|
58
|
+
data['id'] = user_id
|
59
|
+
data
|
34
60
|
end
|
35
61
|
|
62
|
+
# search users with parameters
|
36
63
|
#
|
64
|
+
# @example
|
65
|
+
# search_for_users_by( isAdmin: true )
|
66
|
+
# search_for_users_by( login: 'foo' )
|
67
|
+
#
|
68
|
+
# @return [Array of Hashes] or false
|
37
69
|
#
|
38
70
|
def search_for_users_by( params )
|
39
71
|
|
40
72
|
raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
|
73
|
+
raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
|
41
74
|
|
42
|
-
all_users =
|
75
|
+
all_users = users
|
43
76
|
key, value = params.first
|
44
77
|
|
45
78
|
logger.debug("Searching for users matching '#{key}' = '#{value}'") if @debug
|
46
79
|
users = []
|
47
|
-
|
48
80
|
all_users.dig('message').each do |u|
|
49
81
|
users.push(u) if u.select { |_k,v| v == value }.count >= 1
|
50
82
|
end
|
51
83
|
|
52
|
-
(users.length >= 1 ? users :
|
84
|
+
(users.length >= 1 ? users : nil)
|
53
85
|
end
|
54
86
|
|
55
87
|
# User Update
|
88
|
+
#
|
89
|
+
# @param [Hash] params
|
90
|
+
# @option params [String] email
|
91
|
+
# @option params [String] user_name
|
92
|
+
# @option params [String] login_name
|
93
|
+
# @option params [String] theme
|
94
|
+
#
|
95
|
+
# @example
|
96
|
+
# params = {
|
97
|
+
# email:'user@mygraf.com',
|
98
|
+
# user_name:'User2',
|
99
|
+
# login_name:'user',
|
100
|
+
# theme: 'light'
|
101
|
+
# }
|
102
|
+
# update_user( params )
|
103
|
+
#
|
104
|
+
# @return [Hash]
|
105
|
+
#
|
56
106
|
# PUT /api/users/:id
|
57
|
-
def update_user( params
|
107
|
+
def update_user( params )
|
58
108
|
|
59
109
|
raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
|
60
110
|
|
61
|
-
user_name
|
111
|
+
user_name = validate( params, required: true , var: 'user_name' , type: String )
|
112
|
+
email = validate( params, required: true , var: 'email' , type: String )
|
113
|
+
login_name = validate( params, required: false, var: 'login_name', type: String ) || user_name
|
114
|
+
theme = validate( params, required: false, var: 'theme' , type: String )
|
62
115
|
|
63
|
-
|
64
|
-
|
65
|
-
if( !user_name.is_a?(String) && !user_name.is_a?(Integer) )
|
66
|
-
raise ArgumentError.new('user_name must be an String (for an Username) or an Integer (for an User Id)')
|
67
|
-
end
|
116
|
+
usr = user(user_name)
|
68
117
|
|
69
|
-
|
70
|
-
usr = user_by_name(user_name) if(user_name.is_a?(String))
|
71
|
-
|
72
|
-
if usr.nil? || usr.dig('status').to_i != 200
|
73
|
-
return {
|
74
|
-
'status' => 404,
|
75
|
-
'message' => format('User \'%s\' not found', user_name)
|
76
|
-
}
|
77
|
-
end
|
118
|
+
return { 'status' => 404, 'message' => format('User \'%s\' not found', user_name) } if( usr.nil? || usr.dig('status').to_i != 200 )
|
78
119
|
|
79
120
|
user_id = usr.dig('id')
|
80
121
|
|
81
122
|
endpoint = format( '/api/users/%d', user_id )
|
123
|
+
payload = {
|
124
|
+
email: email,
|
125
|
+
name: user_name,
|
126
|
+
login: login_name,
|
127
|
+
theme: theme
|
128
|
+
}
|
129
|
+
payload.reject!{ |_k, v| v.nil? }
|
82
130
|
|
83
131
|
@logger.debug("Updating user with Id #{user_id}") if @debug
|
84
132
|
|
85
|
-
usr
|
86
|
-
|
133
|
+
usr = usr.deep_string_keys
|
134
|
+
payload = payload.deep_string_keys
|
87
135
|
|
88
|
-
|
136
|
+
payload = usr.merge(payload)
|
89
137
|
|
90
|
-
put( endpoint,
|
138
|
+
put( endpoint, payload.to_json )
|
91
139
|
end
|
92
140
|
|
93
141
|
# Get Organisations for user
|
94
|
-
#
|
95
|
-
|
142
|
+
#
|
143
|
+
# @param [Mixed] user_id Username (String) or Userid (Integer)
|
144
|
+
#
|
145
|
+
# @example
|
146
|
+
# user_organizations( 1 )
|
147
|
+
# user_organizations( 'foo' )
|
148
|
+
#
|
149
|
+
# @return [Hash]
|
150
|
+
#
|
151
|
+
def user_organizations( user_id )
|
96
152
|
|
97
|
-
if(
|
98
|
-
raise ArgumentError.new('user must be an String (for an
|
153
|
+
if( user_id.is_a?(String) && user_id.is_a?(Integer) )
|
154
|
+
raise ArgumentError.new(format('wrong type. user \'user_id\' must be an String (for an Username) or an Integer (for an Userid), given \'%s\'', user_id.class.to_s))
|
99
155
|
end
|
156
|
+
raise ArgumentError.new('missing \'user_id\'') if( user_id.size.zero? )
|
100
157
|
|
101
|
-
usr =
|
102
|
-
usr = user_by_name(user) if(user.is_a?(String))
|
158
|
+
usr = user(user_id)
|
103
159
|
|
104
|
-
if
|
105
|
-
return {
|
106
|
-
'status' => 404,
|
107
|
-
'message' => format('User \'%s\' not found', user)
|
108
|
-
}
|
109
|
-
end
|
160
|
+
return { 'status' => 404, 'message' => format('User \'%s\' not found', user_id) } if( usr.nil? || usr.dig('status').to_i != 200 )
|
110
161
|
|
111
162
|
user_id = usr.dig('id')
|
112
163
|
|
113
164
|
endpoint = format('/api/users/%d/orgs', user_id )
|
114
|
-
@logger.debug("Getting organizations for User #{
|
165
|
+
@logger.debug("Getting organizations for User #{user_id} (GET #{endpoint})") if @debug
|
115
166
|
get(endpoint)
|
116
167
|
end
|
117
168
|
|