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.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +8 -3
  3. data/lib/grafana/admin.rb +39 -65
  4. data/lib/grafana/alerts.rb +334 -14
  5. data/lib/grafana/annotations.rb +284 -9
  6. data/lib/grafana/client.rb +38 -1
  7. data/lib/grafana/dashboard.rb +182 -39
  8. data/lib/grafana/dashboard_permissions.rb +132 -0
  9. data/lib/grafana/dashboard_versions.rb +101 -5
  10. data/lib/grafana/datasource.rb +93 -49
  11. data/lib/grafana/folder.rb +198 -0
  12. data/lib/grafana/folder_and_dashboard_search.rb +57 -0
  13. data/lib/grafana/folder_permissions.rb +155 -0
  14. data/lib/grafana/login.rb +41 -35
  15. data/lib/grafana/network.rb +128 -91
  16. data/lib/grafana/organization.rb +65 -34
  17. data/lib/grafana/organizations.rb +119 -175
  18. data/lib/grafana/playlist.rb +599 -0
  19. data/lib/grafana/preferences.rb +122 -0
  20. data/lib/grafana/tags.rb +19 -8
  21. data/lib/grafana/teams.rb +364 -0
  22. data/lib/grafana/tools.rb +44 -12
  23. data/lib/grafana/user.rb +78 -39
  24. data/lib/grafana/users.rb +104 -53
  25. data/lib/grafana/validator.rb +47 -2
  26. data/lib/grafana/version.rb +3 -3
  27. metadata +13 -38
  28. data/doc/Array.html +0 -200
  29. data/doc/Boolean.html +0 -122
  30. data/doc/FalseClass.html +0 -132
  31. data/doc/Grafana.html +0 -172
  32. data/doc/Hash.html +0 -212
  33. data/doc/Logging.html +0 -326
  34. data/doc/Object.html +0 -286
  35. data/doc/Time.html +0 -200
  36. data/doc/TrueClass.html +0 -132
  37. data/doc/_index.html +0 -380
  38. data/doc/class_list.html +0 -51
  39. data/doc/file.README.html +0 -117
  40. data/doc/file_list.html +0 -56
  41. data/doc/frames.html +0 -17
  42. data/doc/index.html +0 -117
  43. data/doc/method_list.html +0 -771
  44. 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
- if( text =~ /\s/ && text =~ /-/ )
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
- end
26
+ end
18
27
 
19
- rescue => e
20
- puts e
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 => e
59
- @logger.error("json parse error: #{e}") if @debug
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
- # GET /api/user
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
- # PUT /api/user/password
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 = params.dig(:old_password)
23
- new_password = params.dig(: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, { oldPassword: old_password, newPassword: new_password, confirmNew: new_password }.to_json )
47
+ put( endpoint, payload.to_json )
31
48
  end
32
49
 
33
50
  # Switch user context for signed in user
34
- # POST /api/user/using/:organizationId
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( params.is_a?(String) )
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 org.nil? || org.dig('status').to_i != 200
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
- # GET /api/user/orgs
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
- # POST /api/user/stars/dashboard/:dashboardId
67
- def add_dashboard_star( dashboard )
68
-
69
- if( !dashboard.is_a?(String) && !dashboard.is_a?(Integer) )
70
- raise ArgumentError.new('dashboard must be an String (for an Dashboard name) or an Integer (for an Dashboard ID)')
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(dashboard.is_a?(Integer))
106
+ dashboard_id = dashboard if(dashboard_id.is_a?(Integer))
74
107
 
75
- if(dashboard.is_a?(String))
76
- search = { query: dashboard }
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 id can not be 0') if dashboard_id.zero?
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
- # DELETE /api/user/stars/dashboard/:dashboardId
91
- def remove_dashboard_star( dashboard )
92
-
93
- if( !dashboard.is_a?(String) && !dashboard.is_a?(Integer) )
94
- raise ArgumentError.new('dashboard must be an String (for an Dashboard name) or an Integer (for an Dashboard ID)')
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(dashboard.is_a?(Integer))
98
-
99
- if(dashboard.is_a?(String))
138
+ dashboard_id = dashboard( dashboard_id ) if(dashboard_id.is_a?(Integer))
100
139
 
101
- search = { query: dashboard }
102
- r = search_dashboards( search )
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
- # Search Users
9
- # GET /api/users
10
- def all_users
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
- # GET /api/users/:id
18
- def user_by_id(id)
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
- raise ArgumentError.new('id must be an Integer') unless( id.is_a?(Integer) )
38
+ if(user_id.is_a?(String))
39
+ usrs = users
40
+ usrs = JSON.parse(usrs) if(usrs.is_a?(String))
21
41
 
22
- endpoint = format( '/api/users/%d', id )
23
- @logger.debug("Getting user by Id #{id} (GET #{endpoint})") if @debug
24
- get(endpoint)
25
- end
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
- # Get single user by Username(login) or Email
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
- endpoint = format( '/api/users/lookup?loginOrEmail=%s', URI.escape( name ) )
32
- @logger.debug("Get User by Name (GET #{endpoint})") if @debug
33
- get( endpoint )
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 = self.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 : false)
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 = params.dig(: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
- raise ArgumentError.new('missing \'user_name\'') if( user_name.nil? )
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
- usr = user_by_id(user_name) if(user_name.is_a?(Integer))
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 = usr.deep_string_keys
86
- params = params.deep_string_keys
133
+ usr = usr.deep_string_keys
134
+ payload = payload.deep_string_keys
87
135
 
88
- params = usr.merge(params)
136
+ payload = usr.merge(payload)
89
137
 
90
- put( endpoint, params.to_json )
138
+ put( endpoint, payload.to_json )
91
139
  end
92
140
 
93
141
  # Get Organisations for user
94
- # GET /api/users/:id/orgs
95
- def user_organizations(user)
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( !user.is_a?(String) && !user.is_a?(Integer) )
98
- raise ArgumentError.new('user must be an String (for an Dashboard name) or an Integer (for an Dashboard ID)')
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 = user_by_id(user) if(user.is_a?(Integer))
102
- usr = user_by_name(user) if(user.is_a?(String))
158
+ usr = user(user_id)
103
159
 
104
- if usr.nil? || usr.dig('status').to_i != 200
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 #{user} (GET #{endpoint})") if @debug
165
+ @logger.debug("Getting organizations for User #{user_id} (GET #{endpoint})") if @debug
115
166
  get(endpoint)
116
167
  end
117
168