sensu-settings 0.0.1

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.
@@ -0,0 +1,76 @@
1
+ require "sensu/settings/rules"
2
+ require "sensu/settings/validators"
3
+ require "sensu/settings/constants"
4
+
5
+ module Sensu
6
+ module Settings
7
+ class Validator
8
+ include Rules
9
+ include Validators
10
+
11
+ # @!attribute [r] failures
12
+ # @return [Array] validation failures.
13
+ attr_reader :failures
14
+
15
+ def initialize
16
+ @failures = []
17
+ end
18
+
19
+ # Run the validator.
20
+ #
21
+ # @param settings [Hash] sensu settings to validate.
22
+ # @param service [String] sensu service to validate for.
23
+ # @return [Array] validation failures.
24
+ def run(settings, service=nil)
25
+ validate_categories(settings)
26
+ validate_transport(settings[:transport])
27
+ case service
28
+ when "client"
29
+ validate_client(settings[:client])
30
+ when "api"
31
+ validate_api(settings[:api])
32
+ end
33
+ @failures
34
+ end
35
+
36
+ def reset!
37
+ failure_count = @failures.size
38
+ @failures = []
39
+ failure_count
40
+ end
41
+ alias_method :reset, :reset!
42
+
43
+ private
44
+
45
+ # Validate setting categories: checks, filters, mutators, and
46
+ # handlers.
47
+ #
48
+ # @param settings [Hash] sensu settings to validate.
49
+ def validate_categories(settings)
50
+ CATEGORIES.each do |category|
51
+ if is_a_hash?(settings[category])
52
+ validate_method = ("validate_" + category.to_s.chop).to_sym
53
+ settings[category].each do |name, details|
54
+ send(validate_method, details.merge(:name => name.to_s))
55
+ end
56
+ else
57
+ invalid(settings[category], "#{category} must be a hash")
58
+ end
59
+ end
60
+ end
61
+
62
+ # Record an invalid object with a message.
63
+ #
64
+ # @param object [Object] invalid object.
65
+ # @param message [String] message explaining why the object is
66
+ # invalid.
67
+ # @return [Array] current validation failures.
68
+ def invalid(object, message)
69
+ @failures << {
70
+ :object => object,
71
+ :message => message
72
+ }
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,23 @@
1
+ require "sensu/settings/validators/subdue"
2
+ require "sensu/settings/validators/check"
3
+ require "sensu/settings/validators/filter"
4
+ require "sensu/settings/validators/mutator"
5
+ require "sensu/settings/validators/handler"
6
+ require "sensu/settings/validators/client"
7
+ require "sensu/settings/validators/api"
8
+ require "sensu/settings/validators/transport"
9
+
10
+ module Sensu
11
+ module Settings
12
+ module Validators
13
+ include Subdue
14
+ include Check
15
+ include Filter
16
+ include Mutator
17
+ include Handler
18
+ include Client
19
+ include API
20
+ include Transport
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,36 @@
1
+ module Sensu
2
+ module Settings
3
+ module Validators
4
+ module API
5
+ # Validate API authentication.
6
+ # Validates: user, password
7
+ #
8
+ # @param api [Hash] sensu api definition.
9
+ def validate_api_authentication(api)
10
+ if either_are_set?(api[:user], api[:password])
11
+ must_be_a_string(api[:user]) ||
12
+ invalid(api, "api user must be a string")
13
+ must_be_a_string(api[:password]) ||
14
+ invalid(api, "api password must be a string")
15
+ end
16
+ end
17
+
18
+ # Validate a Sensu API definition.
19
+ # Validates: port, bind
20
+ #
21
+ # @param api [Hash] sensu api definition.
22
+ def validate_api(api)
23
+ if is_a_hash?(api)
24
+ must_be_an_integer(api[:port]) ||
25
+ invalid(api, "api port must be an integer")
26
+ must_be_a_string_if_set(api[:bind]) ||
27
+ invalid(api, "api bind must be a string")
28
+ validate_api_authentication(api)
29
+ else
30
+ invalid(api, "api must be a hash")
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,78 @@
1
+ module Sensu
2
+ module Settings
3
+ module Validators
4
+ module Check
5
+ # Validate check scheduling.
6
+ # Validates: interval, standalone, subscribers
7
+ #
8
+ # @param check [Hash] sensu check definition.
9
+ def validate_check_scheduling(check)
10
+ must_be_boolean_if_set(check[:publish]) ||
11
+ invalid(check, "check publish must be boolean")
12
+ unless check[:publish] == false
13
+ (must_be_an_integer(check[:interval]) && check[:interval] > 0) ||
14
+ invalid(check, "check interval must be an integer")
15
+ end
16
+ must_be_boolean_if_set(check[:standalone]) ||
17
+ invalid(check, "check standalone must be boolean")
18
+ unless check[:standalone]
19
+ if is_an_array?(check[:subscribers])
20
+ items_must_be_strings(check[:subscribers]) ||
21
+ invalid(check, "check subscribers must each be a string")
22
+ else
23
+ invalid(check, "check subscribers must be an array")
24
+ end
25
+ end
26
+ end
27
+
28
+ # Validate check handling.
29
+ # Validates: handler, handlers
30
+ #
31
+ # @param check [Hash] sensu check definition.
32
+ def validate_check_handling(check)
33
+ must_be_a_string_if_set(check[:handler]) ||
34
+ invalid(check, "check handler must be a string")
35
+ must_be_an_array_if_set(check[:handlers]) ||
36
+ invalid(check, "check handlers must be an array")
37
+ if is_an_array?(check[:handlers])
38
+ items_must_be_strings(check[:handlers]) ||
39
+ invalid(check, "check handlers must each be a string")
40
+ end
41
+ end
42
+
43
+ # Validate check flap detection.
44
+ # Validates: low_flap_threshold, high_flap_threshold
45
+ #
46
+ # @param check [Hash] sensu check definition.
47
+ def validate_check_flap_detection(check)
48
+ if either_are_set?(check[:low_flap_threshold], check[:high_flap_threshold])
49
+ must_be_an_integer(check[:low_flap_threshold]) ||
50
+ invalid(check, "check low flap threshold must be an integer")
51
+ must_be_an_integer(check[:high_flap_threshold]) ||
52
+ invalid(check, "check high flap threshold must be an integer")
53
+ end
54
+ end
55
+
56
+ # Validate a Sensu check definition.
57
+ #
58
+ # @param check [Hash] sensu check definition.
59
+ def validate_check(check)
60
+ must_be_a_string(check[:name]) ||
61
+ invalid(check, "check name must be a string")
62
+ must_match_regex(/^[\w\.-]+$/, check[:name]) ||
63
+ invalid(check, "check name cannot contain spaces or special characters")
64
+ must_be_a_string(check[:command]) ||
65
+ invalid(check, "check command must be a string")
66
+ must_be_a_numeric_if_set(check[:timeout]) ||
67
+ invalid(check, "check timeout must be numeric")
68
+ validate_check_scheduling(check)
69
+ validate_check_handling(check)
70
+ validate_check_flap_detection(check)
71
+ if check[:subdue]
72
+ validate_subdue(check)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,113 @@
1
+ module Sensu
2
+ module Settings
3
+ module Validators
4
+ module Client
5
+ # Validate client subscriptions.
6
+ # Validates: subscriptions
7
+ #
8
+ # @param client [Hash] sensu client definition.
9
+ def validate_client_subscriptions(client)
10
+ if is_an_array?(client[:subscriptions])
11
+ items_must_be_strings(client[:subscriptions]) ||
12
+ invalid(client, "client subscriptions must each be a string")
13
+ else
14
+ invalid(client, "client subscriptions must be an array")
15
+ end
16
+ end
17
+
18
+ # Validate client socket.
19
+ # Validates: socket (bind, port)
20
+ #
21
+ # @param client [Hash] sensu client definition.
22
+ def validate_client_socket(client)
23
+ must_be_a_hash_if_set(client[:socket]) ||
24
+ invalid(client, "client socket must be a hash")
25
+ if is_a_hash?(client[:socket])
26
+ must_be_a_string_if_set(client[:socket][:bind]) ||
27
+ invalid(client, "client socket bind must be a string")
28
+ must_be_an_integer_if_set(client[:socket][:port]) ||
29
+ invalid(client, "client socket port must be an integer")
30
+ end
31
+ end
32
+
33
+ # Validate client keepalive handlers.
34
+ # Validates: keepalive (handler, handlers)
35
+ #
36
+ # @param client [Hash] sensu client definition.
37
+ def validate_client_keepalive_handlers(client)
38
+ must_be_a_string_if_set(client[:keepalive][:handler]) ||
39
+ invalid(client, "client keepalive handler must be a string")
40
+ must_be_an_array_if_set(client[:keepalive][:handlers]) ||
41
+ invalid(client, "client keepalive handlers must be an array")
42
+ if is_an_array?(client[:keepalive][:handlers])
43
+ items_must_be_strings(client[:keepalive][:handlers]) ||
44
+ invalid(client, "client keepalive handlers must each be a string")
45
+ end
46
+ end
47
+
48
+ # Validate client keepalive thresholds.
49
+ # Validates: keepalive (thresholds)
50
+ #
51
+ # @param client [Hash] sensu client definition.
52
+ def validate_client_keepalive_thresholds(client)
53
+ thresholds = client[:keepalive][:thresholds]
54
+ must_be_a_hash_if_set(thresholds) ||
55
+ invalid(client, "client keepalive thresholds must be a hash")
56
+ if is_a_hash?(thresholds)
57
+ must_be_an_integer_if_set(thresholds[:warning]) ||
58
+ invalid(client, "client keepalive warning threshold must be an integer")
59
+ must_be_an_integer_if_set(thresholds[:critical]) ||
60
+ invalid(client, "client keepalive critical threshold must be an integer")
61
+ end
62
+ end
63
+
64
+ # Validate client keepalive.
65
+ # Validates: keepalive
66
+ #
67
+ # @param client [Hash] sensu client definition.
68
+ def validate_client_keepalive(client)
69
+ must_be_a_hash_if_set(client[:keepalive]) ||
70
+ invalid(client, "client keepalive must be a hash")
71
+ if is_a_hash?(client[:keepalive])
72
+ validate_client_keepalive_handlers(client)
73
+ validate_client_keepalive_thresholds(client)
74
+ end
75
+ end
76
+
77
+ # Validate client redact.
78
+ # Validates: redact
79
+ #
80
+ # @param client [Hash] sensu client definition.
81
+ def validate_client_redact(client)
82
+ must_be_an_array_if_set(client[:redact]) ||
83
+ invalid(client, "client redact must be an array")
84
+ if is_an_array?(client[:redact])
85
+ items_must_be_strings(client[:redact]) ||
86
+ invalid(client, "client redact keys must each be a string")
87
+ end
88
+ end
89
+
90
+ # Validate a Sensu client definition.
91
+ # Validates: name, address
92
+ #
93
+ # @param client [Hash] sensu client definition.
94
+ def validate_client(client)
95
+ must_be_a_hash(client) ||
96
+ invalid(client, "client must be a hash")
97
+ if is_a_hash?(client)
98
+ must_be_a_string(client[:name]) ||
99
+ invalid(client, "client name must be a string")
100
+ must_match_regex(/^[\w\.-]+$/, client[:name]) ||
101
+ invalid(client, "client name cannot contain spaces or special characters")
102
+ must_be_a_string(client[:address]) ||
103
+ invalid(client, "client address must be a string")
104
+ validate_client_subscriptions(client)
105
+ validate_client_socket(client)
106
+ validate_client_keepalive(client)
107
+ validate_client_redact(client)
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,18 @@
1
+ module Sensu
2
+ module Settings
3
+ module Validators
4
+ module Filter
5
+ # Validate a Sensu filter definition.
6
+ # Validates: attributes, negate
7
+ #
8
+ # @param filter [Hash] sensu filter definition.
9
+ def validate_filter(filter)
10
+ must_be_boolean_if_set(filter[:negate]) ||
11
+ invalid(filter, "filter negate must be boolean")
12
+ must_be_a_hash(filter[:attributes]) ||
13
+ invalid(filter, "filter attributes must be a hash")
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,133 @@
1
+ module Sensu
2
+ module Settings
3
+ module Validators
4
+ module Handler
5
+ # Validate pipe handler.
6
+ # Validates: command
7
+ #
8
+ # @param handler [Hash] sensu handler definition.
9
+ def validate_pipe_handler(handler)
10
+ must_be_a_string(handler[:command]) ||
11
+ invalid(handler, "handler command must be a string")
12
+ end
13
+
14
+ # Validate socket (tcp/udp) handler.
15
+ # Validates: socket (host, port)
16
+ #
17
+ # @param handler [Hash] sensu handler definition.
18
+ def validate_socket_handler(handler)
19
+ socket = handler[:socket]
20
+ if is_a_hash?(socket)
21
+ must_be_a_string(socket[:host]) ||
22
+ invalid(handler, "handler host must be a string")
23
+ must_be_an_integer(socket[:port]) ||
24
+ invalid(handler, "handler port must be an integer")
25
+ else
26
+ invalid(handler, "handler socket must be a hash")
27
+ end
28
+ end
29
+
30
+ # Validate transport handler.
31
+ # Validates: pipe (type, name, options)
32
+ #
33
+ # @param handler [Hash] sensu handler definition.
34
+ def validate_transport_handler(handler)
35
+ pipe = handler[:pipe]
36
+ if is_a_hash?(pipe)
37
+ must_be_a_string(pipe[:type]) ||
38
+ invalid(handler, "handler transport pipe type must be a string")
39
+ must_be_either(%w[direct fanout topic], pipe[:type]) ||
40
+ invalid(handler, "handler transport pipe type is invalid")
41
+ must_be_a_string(pipe[:name]) ||
42
+ invalid(handler, "handler transport pipe name must be a string")
43
+ must_be_a_hash_if_set(pipe[:options]) ||
44
+ invalid(handler, "handler transport pipe options must be a hash")
45
+ else
46
+ invalid(handler, "handler transport pipe must be a hash")
47
+ end
48
+ end
49
+
50
+ # Validate set handler.
51
+ # Validates: handlers
52
+ #
53
+ # @param handler [Hash] sensu handler definition.
54
+ def validate_set_handler(handler)
55
+ if is_an_array?(handler[:handlers])
56
+ items_must_be_strings(handler[:handlers]) ||
57
+ invalid(handler, "handler set handlers must each be a string")
58
+ else
59
+ invalid(handler, "handler set handlers must be an array")
60
+ end
61
+ end
62
+
63
+ # Validate handler type.
64
+ # Validates: type
65
+ #
66
+ # @param handler [Hash] sensu handler definition.
67
+ def validate_handler_type(handler)
68
+ must_be_a_string(handler[:type]) ||
69
+ invalid(handler, "handler type must be a string")
70
+ case handler[:type]
71
+ when "pipe"
72
+ validate_pipe_handler(handler)
73
+ when "tcp", "udp"
74
+ validate_socket_handler(handler)
75
+ when "transport"
76
+ validate_transport_handler(handler)
77
+ when "set"
78
+ validate_set_handler(handler)
79
+ else
80
+ invalid(handler, "unknown handler type")
81
+ end
82
+ end
83
+
84
+ # Validate handler filtering.
85
+ # Validates: filter, filters
86
+ #
87
+ # @param handler [Hash] sensu handler definition.
88
+ def validate_handler_filtering(handler)
89
+ must_be_an_array_if_set(handler[:filters]) ||
90
+ invalid(handler, "handler filters must be an array")
91
+ if is_an_array?(handler[:filters])
92
+ items_must_be_strings(handler[:filters]) ||
93
+ invalid(handler, "handler filters items must be strings")
94
+ end
95
+ must_be_a_string_if_set(handler[:filter]) ||
96
+ invalid(handler, "handler filter must be a string")
97
+ end
98
+
99
+ # Validate handler severities.
100
+ # Validates: severities
101
+ #
102
+ # @param handler [Hash] sensu handler definition.
103
+ def validate_handler_severities(handler)
104
+ must_be_an_array_if_set(handler[:severities]) ||
105
+ invalid(handler, "handler severities must be an array")
106
+ if is_an_array?(handler[:severities])
107
+ must_be_either(%w[ok warning critical unknown], handler[:severities]) ||
108
+ invalid(handler, "handler severities are invalid")
109
+ end
110
+ end
111
+
112
+ # Validate a Sensu handler definition.
113
+ # Validates: timeout, mutator, handle_flapping
114
+ #
115
+ # @param handler [Hash] sensu handler definition.
116
+ def validate_handler(handler)
117
+ validate_handler_type(handler)
118
+ validate_handler_filtering(handler)
119
+ validate_handler_severities(handler)
120
+ must_be_a_numeric_if_set(handler[:timeout]) ||
121
+ invalid(handler, "handler timeout must be numeric")
122
+ must_be_a_string_if_set(handler[:mutator]) ||
123
+ invalid(handler, "handler mutator must be a string")
124
+ must_be_boolean_if_set(handler[:handle_flapping]) ||
125
+ invalid(handler, "handler handle_flapping must be boolean")
126
+ if handler[:subdue]
127
+ validate_subdue(handler)
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end