icinga2 0.9.2.1 → 0.9.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -22
  3. data/doc/Array.html +4 -6
  4. data/doc/Boolean.html +4 -6
  5. data/doc/FalseClass.html +4 -6
  6. data/doc/Hash.html +126 -8
  7. data/doc/Icinga2.html +7 -9
  8. data/doc/Logging.html +5 -7
  9. data/doc/Object.html +8 -10
  10. data/doc/Time.html +4 -6
  11. data/doc/TrueClass.html +4 -6
  12. data/doc/_index.html +20 -7
  13. data/doc/class_list.html +1 -1
  14. data/doc/file.README.html +32 -30
  15. data/doc/frames.html +1 -1
  16. data/doc/index.html +32 -30
  17. data/doc/method_list.html +34 -2
  18. data/doc/services.md +45 -62
  19. data/doc/top-level-namespace.html +4 -6
  20. data/examples/_blank.rb +2 -2
  21. data/examples/config.rb +23 -0
  22. data/examples/downtimes.rb +4 -33
  23. data/examples/hostgroups.rb +4 -33
  24. data/examples/hosts.rb +18 -33
  25. data/examples/informations.rb +4 -33
  26. data/examples/notifications.rb +4 -33
  27. data/examples/servicegroups.rb +4 -25
  28. data/examples/services.rb +46 -67
  29. data/examples/statistics.rb +4 -33
  30. data/examples/test.rb +7 -28
  31. data/examples/usergroups.rb +4 -33
  32. data/examples/users.rb +4 -33
  33. data/lib/icinga2/client.rb +16 -42
  34. data/lib/icinga2/converts.rb +16 -54
  35. data/lib/icinga2/downtimes.rb +46 -44
  36. data/lib/icinga2/hostgroups.rb +35 -35
  37. data/lib/icinga2/hosts.rb +235 -228
  38. data/lib/icinga2/network.rb +53 -125
  39. data/lib/icinga2/notifications.rb +37 -46
  40. data/lib/icinga2/servicegroups.rb +31 -41
  41. data/lib/icinga2/services.rb +211 -236
  42. data/lib/icinga2/tools.rb +10 -9
  43. data/lib/icinga2/usergroups.rb +22 -32
  44. data/lib/icinga2/users.rb +64 -59
  45. data/lib/icinga2/validator.rb +59 -0
  46. data/lib/icinga2/version.rb +1 -1
  47. metadata +78 -7
  48. data/lib/icinga2/network.rb-SAVE +0 -1004
@@ -45,7 +45,7 @@ module Icinga2
45
45
 
46
46
  # return count of handled problems
47
47
  #
48
- # @param [Hash] objects
48
+ # @param [Array] objects
49
49
  # @param [Integer] state (nil)
50
50
  #
51
51
  # @example for host objects
@@ -66,16 +66,17 @@ module Icinga2
66
66
  #
67
67
  def count_problems( objects, state = nil )
68
68
 
69
- compare_states = []
69
+ raise ArgumentError.new(format('wrong type. \'objects\' must be an Array, given \'%s\'', objects.class.to_s)) unless( objects.is_a?(Array) )
70
+ #raise ArgumentError.new('missing objects') if( objects.size.zero? )
70
71
 
71
- unless( state.nil? )
72
+ raise ArgumentError.new(format('wrong type. \'state\' must be an Integer, given \'%s\'', state.class.to_s)) unless( state.nil? || state.is_a?(Integer) )
72
73
 
73
- # 0 = "Up" or "OK"
74
- # 1 = "Down" or "Warning"
75
- # 2 = "Critical"
76
- # 3 = "Unknown"
77
- compare_states = [1, 2, 3]
78
- end
74
+ # 0 = "Up" or "OK"
75
+ # 1 = "Down" or "Warning"
76
+ # 2 = "Critical"
77
+ # 3 = "Unknown"
78
+ compare_states = []
79
+ compare_states = [1, 2, 3] unless( state.nil? )
79
80
 
80
81
  compare_states.push(state) if( state.is_a?(Integer) )
81
82
 
@@ -9,8 +9,8 @@ module Icinga2
9
9
  # add a usergroup
10
10
  #
11
11
  # @param [Hash] params
12
- # @option params [String] :user_group usergroup to create
13
- # @option params [String] :display_name the displayed name
12
+ # @option params [String] user_group usergroup to create
13
+ # @option params [String] display_name the displayed name
14
14
  #
15
15
  # @example
16
16
  # @icinga.add_usergroup(user_group: 'foo', display_name: 'FOO')
@@ -22,17 +22,19 @@ module Icinga2
22
22
  raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
23
23
  raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
24
24
 
25
- user_group = params.dig(:user_group)
26
- display_name = params.dig(:display_name)
27
-
28
- raise ArgumentError.new('Missing user_group') if( user_group.nil? )
25
+ user_group = validate( params, required: true, var: 'user_group', type: String )
26
+ display_name = validate( params, required: false, var: 'display_name', type: String )
29
27
 
30
28
  payload = {
31
- 'attrs' => {
32
- 'display_name' => display_name
29
+ attrs: {
30
+ display_name: display_name
33
31
  }
34
32
  }
35
33
 
34
+ # remove all empty attrs
35
+ payload.reject!{ |_k, v| v.nil? }
36
+ payload[:attrs].reject!{ |_k, v| v.nil? }
37
+
36
38
  put(
37
39
  url: format( '%s/objects/usergroups/%s', @icinga_api_url_base, user_group ),
38
40
  headers: @headers,
@@ -43,22 +45,17 @@ module Icinga2
43
45
 
44
46
  # delete a usergroup
45
47
  #
46
- # @param [Hash] params
47
- # @option params [String] :user_group usergroup to delete
48
+ # @param [String] user_group usergroup to delete
48
49
  #
49
50
  # @example
50
- # @icinga.delete_usergroup(user_group: 'foo')
51
+ # @icinga.delete_usergroup('foo')
51
52
  #
52
53
  # @return [Hash] result
53
54
  #
54
- def delete_usergroup( params )
55
-
56
- raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
57
- raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
58
-
59
- user_group = params.dig(:user_group)
55
+ def delete_usergroup( user_group )
60
56
 
61
- raise ArgumentError.new('Missing user_group') if( user_group.nil? )
57
+ raise ArgumentError.new(format('wrong type. \'user_group\' must be an String, given \'%s\'', user_group.class.to_s)) unless( user_group.is_a?(String) )
58
+ raise ArgumentError.new('missing \'user_group\'') if( user_group.size.zero? )
62
59
 
63
60
  delete(
64
61
  url: format( '%s/objects/usergroups/%s?cascade=1', @icinga_api_url_base, user_group ),
@@ -69,27 +66,20 @@ module Icinga2
69
66
 
70
67
  # returns all usersgroups
71
68
  #
72
- # @param [Hash] params
73
- # @option params [String] :user_group ('') optional for a single usergroup
69
+ # @param [String] user_group (nil) optional for a single usergroup
74
70
  #
75
71
  # @example to get all users
76
72
  # @icinga.usergroups
77
73
  #
78
74
  # @example to get one user
79
- # @icinga.usergroups(user_group: 'icingaadmins')
75
+ # @icinga.usergroups('icingaadmins')
80
76
  #
81
77
  # @return [Hash] returns a hash with all usergroups
82
78
  #
83
- def usergroups( params = {} )
84
-
85
- user_group = params.dig(:user_group)
79
+ def usergroups( user_group = nil )
86
80
 
87
- url =
88
- if( user_group.nil? )
89
- format( '%s/objects/usergroups' , @icinga_api_url_base )
90
- else
91
- format( '%s/objects/usergroups/%s', @icinga_api_url_base, user_group )
92
- end
81
+ url = format( '%s/objects/usergroups' , @icinga_api_url_base )
82
+ url = format( '%s/objects/usergroups/%s', @icinga_api_url_base, user_group ) unless( user_group.nil? )
93
83
 
94
84
  api_data(
95
85
  url: url,
@@ -112,8 +102,8 @@ module Icinga2
112
102
  raise ArgumentError.new(format('wrong type. \'user_group\' must be an String, given \'%s\'', user_group.class.to_s)) unless( user_group.is_a?(String) )
113
103
  raise ArgumentError.new('Missing \'user_group\'') if( user_group.size.zero? )
114
104
 
115
- result = usergroups( user_group: user_group )
116
- result = JSON.parse( result ) if result.is_a?( String )
105
+ result = usergroups( user_group )
106
+ result = JSON.parse( result ) if result.is_a?( String )
117
107
  result = result.first if( result.is_a?(Array) )
118
108
 
119
109
  return false if( result.is_a?(Hash) && result.dig('code') == 404 )
@@ -9,43 +9,47 @@ module Icinga2
9
9
  # add a user
10
10
  #
11
11
  # @param [Hash] params
12
- # @option params [String] :user_name ('') user to create
13
- # @option params [String] :display_name ('') the displayed name
14
- # @option params [String] :email ('') the user email
15
- # @option params [String] :pager ('') optional a pager
16
- # @option params [Bool] :enable_notifications (false) enable notifications for this user
17
- # @option params [Array] :groups ([]) a hash with groups
12
+ # @option params [String] user_name user to create
13
+ # @option params [String] display_name ('') the displayed name
14
+ # @option params [String] email ('') the user email
15
+ # @option params [String] pager ('') optional a pager
16
+ # @option params [Bool] enable_notifications (false) enable notifications for this user
17
+ # @option params [Array] groups ([]) a hash with groups
18
+ # @option params [String] period
19
+ # @option params [Array] states
20
+ # @option params [Array] types
21
+ # @option params [Hash] vars
18
22
  #
19
23
  # @example
20
- # @icinga.add_user(user_name: 'foo', display_name: 'FOO', email: 'foo@bar.com', pager: '0000', groups: ['icingaadmins'])
24
+ # param = {
25
+ # user_name: 'foo',
26
+ # display_name: 'FOO',
27
+ # email: 'foo@bar.com',
28
+ # pager: '0000',
29
+ # groups: ['icingaadmins']
30
+ # }
31
+ # @icinga.add_user(param)
21
32
  #
22
33
  # @return [Hash] result
34
+ # * code [Integer]
35
+ # * message [String]
36
+ # * data (optional)
23
37
  #
24
38
  def add_user( params )
25
39
 
26
40
  raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
27
41
  raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
28
42
 
29
- user_name = params.dig(:user_name)
30
- display_name = params.dig(:display_name)
31
- email = params.dig(:email)
32
- pager = params.dig(:pager)
33
- notifications = params.dig(:enable_notifications) || false
34
- groups = params.dig(:groups) || []
35
-
36
- raise ArgumentError.new('Missing user_name') if( user_name.nil? )
37
- raise ArgumentError.new('groups must be an array') unless( groups.is_a?( Array ) )
38
-
39
- payload = {
40
- 'attrs' => {
41
- 'display_name' => display_name,
42
- 'email' => email,
43
- 'pager' => pager,
44
- 'enable_notifications' => notifications
45
- }
46
- }
47
-
48
- payload['attrs']['groups'] = groups unless groups.empty?
43
+ user_name = validate( params, required: true, var: 'user_name', type: String )
44
+ display_name = validate( params, required: false, var: 'display_name', type: String )
45
+ email = validate( params, required: false, var: 'email', type: String )
46
+ pager = validate( params, required: false, var: 'pager', type: String )
47
+ notifications = validate( params, required: false, var: 'enable_notifications', type: Boolean ) || false
48
+ groups = validate( params, required: false, var: 'groups', type: Array ) || []
49
+ period = validate( params, required: false, var: 'period', type: String )
50
+ states = validate( params, required: false, var: 'states', type: Array )
51
+ types = validate( params, required: false, var: 'types', type: Array )
52
+ vars = validate( params, required: false, var: 'vars', type: Hash ) || {}
49
53
 
50
54
  group_validate = []
51
55
 
@@ -54,16 +58,31 @@ module Icinga2
54
58
  end
55
59
 
56
60
  if( group_validate.count != 0 )
57
-
58
- groups = group_validate.join(', ')
59
-
60
61
  return {
61
- status: 404,
62
- message: "these groups are not exists: #{groups}",
63
- data: params
62
+ 'code' => 404,
63
+ 'message' => format('these groups are not exists: \'%s\'', group_validate.join(', ')),
64
+ 'data' => params
64
65
  }
65
66
  end
66
67
 
68
+ payload = {
69
+ attrs: {
70
+ display_name: display_name,
71
+ email: email,
72
+ pager: pager,
73
+ enable_notifications: notifications,
74
+ groups: groups,
75
+ period: period,
76
+ states: states,
77
+ types: types,
78
+ vars: vars
79
+ }
80
+ }
81
+
82
+ # remove all empty attrs
83
+ payload.reject!{ |_k, v| v.nil? }
84
+ payload[:attrs].reject!{ |_k, v| v.nil? }
85
+
67
86
  put(
68
87
  url: format( '%s/objects/users/%s', @icinga_api_url_base, user_name ),
69
88
  headers: @headers,
@@ -74,22 +93,17 @@ module Icinga2
74
93
 
75
94
  # delete a user
76
95
  #
77
- # @param [Hash] params
78
- # @option params [String] :user_name user to delete
96
+ # @param [String] user_name user to delete
79
97
  #
80
98
  # @example
81
- # @icinga.delete_user(user_name: 'foo')
99
+ # @icinga.delete_user('foo')
82
100
  #
83
101
  # @return [Hash] result
84
102
  #
85
- def delete_user( params )
86
-
87
- raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
88
- raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
89
-
90
- user_name = params.dig(:user_name)
103
+ def delete_user( user_name )
91
104
 
92
- raise ArgumentError.new('Missing user_name') if( user_name.nil? )
105
+ raise ArgumentError.new(format('wrong type. \'user_name\' must be an String, given \'%s\'',user_name.class.to_s)) unless( user_name.is_a?(String) )
106
+ raise ArgumentError.new('Missing user_name') if( user_name.size.zero? )
93
107
 
94
108
  delete(
95
109
  url: format( '%s/objects/users/%s?cascade=1', @icinga_api_url_base, user_name ),
@@ -100,29 +114,20 @@ module Icinga2
100
114
 
101
115
  # returns a named or all users
102
116
  #
103
- # @param [Hash] params
104
- # @option params [String] :user_name ('') optional for a single user
117
+ # @param [String] user_name ('') optional for a single user
105
118
  #
106
119
  # @example to get all users
107
120
  # @icinga.users
108
121
  #
109
122
  # @example to get one user
110
- # @icinga.users(user_name: 'icingaadmin')
123
+ # @icinga.users('icingaadmin')
111
124
  #
112
125
  # @return [Array]
113
126
  #
114
- def users( params = {} )
115
-
116
- raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
127
+ def users( user_name = nil )
117
128
 
118
- user_name = params.dig(:user_name)
119
-
120
- url =
121
- if( user_name.nil? )
122
- format( '%s/objects/users' , @icinga_api_url_base )
123
- else
124
- format( '%s/objects/users/%s', @icinga_api_url_base, user_name )
125
- end
129
+ url = format( '%s/objects/users' , @icinga_api_url_base )
130
+ url = format( '%s/objects/users/%s', @icinga_api_url_base, user_name ) unless( user_name.nil? )
126
131
 
127
132
  api_data(
128
133
  url: url,
@@ -145,8 +150,8 @@ module Icinga2
145
150
  raise ArgumentError.new(format('wrong type. \'user_name\' must be an String, given \'%s\'', user_name.class.to_s)) unless( user_name.is_a?(String) )
146
151
  raise ArgumentError.new('Missing \'user_name\'') if( user_name.size.zero? )
147
152
 
148
- result = users( user_name: user_name )
149
- result = JSON.parse( result ) if result.is_a?( String )
153
+ result = users( user_name )
154
+ result = JSON.parse( result ) if result.is_a?( String )
150
155
  result = result.first if( result.is_a?(Array) )
151
156
 
152
157
  return false if( result.is_a?(Hash) && result.dig('code') == 404 )
@@ -0,0 +1,59 @@
1
+
2
+ class Hash
3
+ def assert_required_keys(*keys)
4
+ keys.flatten.each do |key|
5
+ raise ArgumentError.new("Required key: #{key.inspect}") unless key?(key)
6
+ end
7
+ end
8
+
9
+ def assert_valid_keys(params, *valid_keys)
10
+ valid_keys.flatten!
11
+ params.each_key do |k|
12
+ unless valid_keys.include?(k)
13
+ raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+
20
+ module Icinga2
21
+
22
+ # namespace for validate options
23
+ module Validator
24
+
25
+ def validate_options!(params, options)
26
+ options[:optional] ||= []
27
+ options[:required] ||= []
28
+
29
+ params = params.deep_symbolize_keys
30
+ params.assert_required_keys(options[:required])
31
+ params.assert_valid_keys(params, options[:required] + options[:optional])
32
+ end
33
+
34
+ # validate( params, { required: true, var: name, type: String } )
35
+ def validate( params, options )
36
+ required = options.dig(:required) || false
37
+ var = options.dig(:var)
38
+ type = options.dig(:type)
39
+
40
+ params = params.deep_symbolize_keys
41
+
42
+ variable = params.dig(var.to_sym)
43
+
44
+ # puts params
45
+ # puts options
46
+
47
+ clazz = Object.const_get(type.to_s)
48
+
49
+ if(required == true )
50
+ raise ArgumentError.new(format('\'%s\' is requiered and missing!', var)) if(variable.nil?)
51
+ end
52
+
53
+ raise ArgumentError.new(format('wrong type. \'%s\' must be an %s, given \'%s\'', var, type, variable.class.to_s)) unless( variable.nil? || variable.is_a?(clazz) )
54
+
55
+ variable
56
+ end
57
+
58
+ end
59
+ end
@@ -4,6 +4,6 @@
4
4
  module Icinga2
5
5
 
6
6
  # Current version of gem.
7
- VERSION = '0.9.2.1' # [Version::MAJOR, Version::MINOR, Version::TINY, Version::PATCH].compact * '.'
7
+ VERSION = '0.9.2.8'.freeze # [Version::MAJOR, Version::MINOR, Version::TINY, Version::PATCH].compact * '.'
8
8
 
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: icinga2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2.1
4
+ version: 0.9.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bodo Schulz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-16 00:00:00.000000000 Z
11
+ date: 2017-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby_dig
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.1'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rest-client
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -39,19 +53,61 @@ dependencies:
39
53
  - !ruby/object:Gem::Version
40
54
  version: '2.0'
41
55
  - !ruby/object:Gem::Dependency
42
- name: json
56
+ name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '2.1'
48
- type: :runtime
61
+ version: '0'
62
+ type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '2.1'
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake-notes
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.49.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.49.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-checkstyle_formatter
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
55
111
  - !ruby/object:Gem::Dependency
56
112
  name: rspec
57
113
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +122,20 @@ dependencies:
66
122
  - - "~>"
67
123
  - !ruby/object:Gem::Version
68
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec_junit_formatter
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
69
139
  - !ruby/object:Gem::Dependency
70
140
  name: rspec-nc
71
141
  requirement: !ruby/object:Gem::Requirement
@@ -187,6 +257,7 @@ files:
187
257
  - doc/usergroups.md
188
258
  - doc/users.md
189
259
  - examples/_blank.rb
260
+ - examples/config.rb
190
261
  - examples/downtimes.rb
191
262
  - examples/hostgroups.rb
192
263
  - examples/hosts.rb
@@ -205,7 +276,6 @@ files:
205
276
  - lib/icinga2/hostgroups.rb
206
277
  - lib/icinga2/hosts.rb
207
278
  - lib/icinga2/network.rb
208
- - lib/icinga2/network.rb-SAVE
209
279
  - lib/icinga2/notifications.rb
210
280
  - lib/icinga2/servicegroups.rb
211
281
  - lib/icinga2/services.rb
@@ -213,6 +283,7 @@ files:
213
283
  - lib/icinga2/tools.rb
214
284
  - lib/icinga2/usergroups.rb
215
285
  - lib/icinga2/users.rb
286
+ - lib/icinga2/validator.rb
216
287
  - lib/icinga2/version.rb
217
288
  - lib/logging.rb
218
289
  - lib/monkey_patches.rb