smart_proxy_monitoring 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.
- checksums.yaml +7 -0
- data/LICENSE +675 -0
- data/README.md +174 -0
- data/bundler.d/monitoring.rb +2 -0
- data/lib/smart_proxy_monitoring/configuration_loader.rb +8 -0
- data/lib/smart_proxy_monitoring/dependency_injection.rb +8 -0
- data/lib/smart_proxy_monitoring/monitoring_api.rb +77 -0
- data/lib/smart_proxy_monitoring/monitoring_http_config.ru +5 -0
- data/lib/smart_proxy_monitoring/monitoring_plugin.rb +19 -0
- data/lib/smart_proxy_monitoring/version.rb +5 -0
- data/lib/smart_proxy_monitoring.rb +4 -0
- data/lib/smart_proxy_monitoring_common/monitoring_common.rb +6 -0
- data/lib/smart_proxy_monitoring_icinga2/icinga2_api_observer.rb +66 -0
- data/lib/smart_proxy_monitoring_icinga2/icinga2_client.rb +127 -0
- data/lib/smart_proxy_monitoring_icinga2/icinga2_initial_importer.rb +109 -0
- data/lib/smart_proxy_monitoring_icinga2/icinga2_result_uploader.rb +97 -0
- data/lib/smart_proxy_monitoring_icinga2/icinga2_upload_queue.rb +9 -0
- data/lib/smart_proxy_monitoring_icinga2/monitoring_icinga2_common.rb +21 -0
- data/lib/smart_proxy_monitoring_icinga2/monitoring_icinga2_main.rb +68 -0
- data/lib/smart_proxy_monitoring_icinga2/monitoring_icinga2_plugin.rb +16 -0
- data/lib/smart_proxy_monitoring_icinga2/plugin_configuration.rb +28 -0
- data/lib/smart_proxy_monitoring_icinga2.rb +2 -0
- data/settings.d/monitoring.yml.example +11 -0
- data/settings.d/monitoring_icinga2.yml.example +17 -0
- metadata +142 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module ::Proxy::Monitoring::Icinga2
|
4
|
+
class MonitoringResult < Proxy::HttpRequest::ForemanRequest
|
5
|
+
def push_result(result)
|
6
|
+
send_request(request_factory.create_post('api/monitoring_results', result))
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Icinga2ResultUploader
|
11
|
+
include ::Proxy::Log
|
12
|
+
include ::Proxy::Monitoring::Icinga2::Common
|
13
|
+
|
14
|
+
attr_reader :semaphore
|
15
|
+
|
16
|
+
def initialize(queue)
|
17
|
+
@queue = queue.queue
|
18
|
+
@semaphore = Mutex.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def upload
|
22
|
+
while change = @queue.pop
|
23
|
+
with_event_counter('Icinga2 Result Uploader') do
|
24
|
+
symbolize_keys_deep!(change)
|
25
|
+
|
26
|
+
change[:timestamp] = change[:check_result][:schedule_end] if change.key?(:check_result)
|
27
|
+
if change.key?(:downtime) && change[:downtime].is_a?(Hash)
|
28
|
+
change[:host] = change[:downtime][:host_name] if change[:host].nil? || change[:host].empty?
|
29
|
+
change[:service] = change[:downtime][:service_name] if change[:service].nil? || change[:service].empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
if change[:service].nil? || change[:service].empty?
|
33
|
+
change[:service] = 'Host Check'
|
34
|
+
end
|
35
|
+
|
36
|
+
case change[:type]
|
37
|
+
when 'StateChange'
|
38
|
+
transformed = { result: change[:check_result][:state] }
|
39
|
+
when 'AcknowledgementSet'
|
40
|
+
transformed = { acknowledged: true }
|
41
|
+
when 'AchnowledgementCleared'
|
42
|
+
transformed = { acknowledged: false }
|
43
|
+
when 'DowntimeTriggered'
|
44
|
+
transformed = { downtime: true }
|
45
|
+
when 'DowntimeRemoved'
|
46
|
+
transformed = { downtime: false }
|
47
|
+
when '_parsed'
|
48
|
+
transformed = change.dup.reject! { |k, _v| k == :type }
|
49
|
+
else
|
50
|
+
next
|
51
|
+
end
|
52
|
+
transformed.merge!(
|
53
|
+
host: change[:host],
|
54
|
+
service: change[:service],
|
55
|
+
timestamp: change[:timestamp]
|
56
|
+
)
|
57
|
+
begin
|
58
|
+
MonitoringResult.new.push_result(transformed.to_json)
|
59
|
+
rescue Errno::ECONNREFUSED => e
|
60
|
+
logger.error "Foreman refused connection when tried to upload monitoring result: #{e.message}"
|
61
|
+
sleep 10
|
62
|
+
rescue => e
|
63
|
+
logger.error "Error while uploading monitoring results to Foreman: #{e.message}"
|
64
|
+
sleep 1
|
65
|
+
retry
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def start
|
72
|
+
@thread = Thread.new { upload }
|
73
|
+
@thread.abort_on_exception = true
|
74
|
+
@thread
|
75
|
+
end
|
76
|
+
|
77
|
+
def stop
|
78
|
+
@thread.terminate unless @thread.nil?
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def symbolize_keys_deep!(h)
|
84
|
+
h.keys.each do |k|
|
85
|
+
ks = k.to_sym
|
86
|
+
h[ks] = h.delete k
|
87
|
+
symbolize_keys_deep! h[ks] if h[ks].is_a? Hash
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_domain(host)
|
92
|
+
domain = Proxy::Monitoring::Plugin.settings.strip_domain
|
93
|
+
host = "#{host}#{domain}" unless domain.nil?
|
94
|
+
host
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ::Proxy::Monitoring::Icinga2
|
2
|
+
module Common
|
3
|
+
private
|
4
|
+
|
5
|
+
def with_event_counter(log_prefix, interval_count = 100, interval_seconds = 60)
|
6
|
+
semaphore.synchronize do
|
7
|
+
@counter ||= 0
|
8
|
+
@timer ||= Time.now
|
9
|
+
if @counter >= interval_count || (Time.now - @timer) > interval_seconds
|
10
|
+
status = "#{log_prefix}: Observed #{@counter} events in the last #{(Time.now - @timer).round(2)} seconds."
|
11
|
+
status += " #{@queue.length} items queued. #{@queue.num_waiting} threads waiting." unless @queue.nil?
|
12
|
+
logger.info status
|
13
|
+
@timer = Time.now
|
14
|
+
@counter = 0
|
15
|
+
end
|
16
|
+
@counter += 1
|
17
|
+
end
|
18
|
+
yield
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Proxy::Monitoring::Icinga2
|
2
|
+
class Provider < ::Proxy::Monitoring::Provider
|
3
|
+
include Proxy::Log
|
4
|
+
include Proxy::Util
|
5
|
+
|
6
|
+
def remove_host(host)
|
7
|
+
request_url = "/objects/hosts/#{host}?cascade=1"
|
8
|
+
|
9
|
+
result = with_errorhandling("Remove #{host}") do
|
10
|
+
Icinga2Client.delete(request_url)
|
11
|
+
end
|
12
|
+
result.to_json
|
13
|
+
end
|
14
|
+
|
15
|
+
def remove_downtime_host(host, author, comment)
|
16
|
+
request_url = "/actions/remove-downtime?type=Host&filter=host.name==\"#{host}\"\&\&author==\"#{author}\"\&\&comment=\"#{comment}\""
|
17
|
+
data = {}
|
18
|
+
|
19
|
+
result = with_errorhandling("Remove downtime from #{host}") do
|
20
|
+
Icinga2Client.post(request_url, data.to_json)
|
21
|
+
end
|
22
|
+
result.to_json
|
23
|
+
end
|
24
|
+
|
25
|
+
def set_downtime_host(host, author, comment, start_time, end_time)
|
26
|
+
request_url = "/actions/schedule-downtime?type=Host&filter=host.name==\"#{host}\""
|
27
|
+
data = {
|
28
|
+
'author' => author,
|
29
|
+
'comment' => comment,
|
30
|
+
'start_time' => start_time,
|
31
|
+
'end_time' => end_time,
|
32
|
+
'duration' => 1000
|
33
|
+
}
|
34
|
+
|
35
|
+
result = with_errorhandling("Set downtime on #{host}") do
|
36
|
+
Icinga2Client.post(request_url, data.to_json)
|
37
|
+
end
|
38
|
+
result.to_json
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def with_errorhandling(action)
|
44
|
+
response = yield
|
45
|
+
logger.debug "Monitoring - Action successful: #{action}"
|
46
|
+
result = JSON.parse(response.body)
|
47
|
+
unless result.key?('results')
|
48
|
+
logger.error "Invalid Icinga result or result with errors: #{result.inspect}"
|
49
|
+
raise Proxy::Monitoring::Error.new("Icinga server at #{::Proxy::Monitoring::Icinga2::Plugin.settings.server} returned an invalid result.")
|
50
|
+
end
|
51
|
+
unless result['results'].first
|
52
|
+
raise Proxy::Monitoring::NotFound.new("Icinga server at #{::Proxy::Monitoring::Icinga2::Plugin.settings.server} returned an empty result.")
|
53
|
+
end
|
54
|
+
if result['results'][0]['code'] != 200
|
55
|
+
raise Proxy::Monitoring::Error.new("Icinga server at #{::Proxy::Monitoring::Icinga2::Plugin.settings.server} returned an error: #{result['results'][0]['code']} #{result['results'][0]['status']}")
|
56
|
+
end
|
57
|
+
result
|
58
|
+
rescue JSON::ParserError => e
|
59
|
+
raise Proxy::Monitoring::Error.new("Icinga server at #{::Proxy::Monitoring::Icinga2::Plugin.settings.server} returned invalid JSON: '#{e.message}'")
|
60
|
+
rescue RestClient::Exception => e
|
61
|
+
raise Proxy::Monitoring::Error.new("Icinga server at #{::Proxy::Monitoring::Icinga2::Plugin.settings.server} returned an error: '#{e.response}'")
|
62
|
+
rescue Errno::ECONNREFUSED => e
|
63
|
+
raise Proxy::Monitoring::ConnectionError.new("Icinga server at #{::Proxy::Monitoring::Icinga2::Plugin.settings.server} is not responding")
|
64
|
+
rescue SocketError => e
|
65
|
+
raise Proxy::Monitoring::ConnectionError.new("Icinga server '#{::Proxy::Monitoring::Icinga2::Plugin.settings.server}' is unknown")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ::Proxy::Monitoring::Icinga2
|
2
|
+
class Plugin < ::Proxy::Provider
|
3
|
+
plugin :monitoring_icinga2, ::Proxy::Monitoring::VERSION
|
4
|
+
|
5
|
+
default_settings server: 'localhost'
|
6
|
+
default_settings api_port: '5665'
|
7
|
+
default_settings verify_ssl: true
|
8
|
+
|
9
|
+
requires :monitoring, ::Proxy::Monitoring::VERSION
|
10
|
+
|
11
|
+
start_services :icinga2_initial_importer, :icinga2_api_observer, :icinga2_result_uploader
|
12
|
+
|
13
|
+
load_classes ::Proxy::Monitoring::Icinga2::PluginConfiguration
|
14
|
+
load_dependency_injection_wirings ::Proxy::Monitoring::Icinga2::PluginConfiguration
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ::Proxy::Monitoring::Icinga2
|
2
|
+
class PluginConfiguration
|
3
|
+
def load_classes
|
4
|
+
require 'smart_proxy_monitoring_common/monitoring_common'
|
5
|
+
require 'smart_proxy_monitoring_icinga2/monitoring_icinga2_main'
|
6
|
+
require 'smart_proxy_monitoring_icinga2/monitoring_icinga2_common'
|
7
|
+
require 'smart_proxy_monitoring_icinga2/icinga2_upload_queue'
|
8
|
+
require 'smart_proxy_monitoring_icinga2/icinga2_client'
|
9
|
+
require 'smart_proxy_monitoring_icinga2/icinga2_initial_importer'
|
10
|
+
require 'smart_proxy_monitoring_icinga2/icinga2_api_observer'
|
11
|
+
require 'smart_proxy_monitoring_icinga2/icinga2_result_uploader'
|
12
|
+
end
|
13
|
+
|
14
|
+
def load_dependency_injection_wirings(container_instance, settings)
|
15
|
+
container_instance.dependency :monitoring_provider, lambda { ::Proxy::Monitoring::Icinga2::Provider.new }
|
16
|
+
container_instance.singleton_dependency :icinga2_upload_queue, lambda { ::Proxy::Monitoring::Icinga2::Icinga2UploadQueue.new }
|
17
|
+
container_instance.singleton_dependency :icinga2_api_observer, (lambda do
|
18
|
+
::Proxy::Monitoring::Icinga2::Icinga2ApiObserver.new(container_instance.get_dependency(:icinga2_upload_queue))
|
19
|
+
end)
|
20
|
+
container_instance.singleton_dependency :icinga2_result_uploader, (lambda do
|
21
|
+
::Proxy::Monitoring::Icinga2::Icinga2ResultUploader.new(container_instance.get_dependency(:icinga2_upload_queue))
|
22
|
+
end)
|
23
|
+
container_instance.singleton_dependency :icinga2_initial_importer, (lambda do
|
24
|
+
::Proxy::Monitoring::Icinga2::Icinga2InitialImporter.new(container_instance.get_dependency(:icinga2_upload_queue))
|
25
|
+
end)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
---
|
2
|
+
# Collect Monitoring information
|
3
|
+
:enabled: true
|
4
|
+
|
5
|
+
# Valid providers:
|
6
|
+
# monitoring_icinga2 (Icinga 2 API, default)
|
7
|
+
#:use_provider: monitoring_icinga2
|
8
|
+
|
9
|
+
# Strip this part of the domain when communicating with the Monitoring server
|
10
|
+
# and add it when communicating with Foreman
|
11
|
+
# :strip_domain: .localdomain
|
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
# Collect Monitoring information via Icinga 2 API
|
3
|
+
:enabled: true
|
4
|
+
|
5
|
+
# The FQDN or IP address of the Icinga 2 server (if using IP address also set verify_ssl to false)
|
6
|
+
:server: icinga2.localdomain
|
7
|
+
# The CA certificate used by Icinga 2 (typically located on the server at /etc/icinga2/pki/ca.crt)
|
8
|
+
:api_cacert: /usr/share/foreman-proxy/monitoring/ca.crt
|
9
|
+
# The name of API User
|
10
|
+
:api_user: foreman
|
11
|
+
# The certificate issued on the client_cn attribute of the API User and the corresponding key
|
12
|
+
:api_usercert: /usr/share/foreman-proxy/monitoring/foreman.crt
|
13
|
+
:api_userkey: /usr/share/foreman-proxy/monitoring/foreman.key
|
14
|
+
# The password from the password attribute of the API User (if not using certificates)
|
15
|
+
#:api_password: foreman
|
16
|
+
# SSL Verfification mode (boolean value)
|
17
|
+
:verify_ssl: true
|
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: smart_proxy_monitoring
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Timo Goebel
|
8
|
+
- Dirk Goetz
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-08-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rest-client
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: json
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rake
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: mocha
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: test-unit
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
description: Monitoring plug-in for Foreman's smart proxy
|
85
|
+
email:
|
86
|
+
- timo.goebel@dm.de
|
87
|
+
- dirk.goetz@netways.de
|
88
|
+
executables: []
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files:
|
91
|
+
- README.md
|
92
|
+
- LICENSE
|
93
|
+
files:
|
94
|
+
- LICENSE
|
95
|
+
- README.md
|
96
|
+
- bundler.d/monitoring.rb
|
97
|
+
- lib/smart_proxy_monitoring.rb
|
98
|
+
- lib/smart_proxy_monitoring/configuration_loader.rb
|
99
|
+
- lib/smart_proxy_monitoring/dependency_injection.rb
|
100
|
+
- lib/smart_proxy_monitoring/monitoring_api.rb
|
101
|
+
- lib/smart_proxy_monitoring/monitoring_http_config.ru
|
102
|
+
- lib/smart_proxy_monitoring/monitoring_plugin.rb
|
103
|
+
- lib/smart_proxy_monitoring/version.rb
|
104
|
+
- lib/smart_proxy_monitoring_common/monitoring_common.rb
|
105
|
+
- lib/smart_proxy_monitoring_icinga2.rb
|
106
|
+
- lib/smart_proxy_monitoring_icinga2/icinga2_api_observer.rb
|
107
|
+
- lib/smart_proxy_monitoring_icinga2/icinga2_client.rb
|
108
|
+
- lib/smart_proxy_monitoring_icinga2/icinga2_initial_importer.rb
|
109
|
+
- lib/smart_proxy_monitoring_icinga2/icinga2_result_uploader.rb
|
110
|
+
- lib/smart_proxy_monitoring_icinga2/icinga2_upload_queue.rb
|
111
|
+
- lib/smart_proxy_monitoring_icinga2/monitoring_icinga2_common.rb
|
112
|
+
- lib/smart_proxy_monitoring_icinga2/monitoring_icinga2_main.rb
|
113
|
+
- lib/smart_proxy_monitoring_icinga2/monitoring_icinga2_plugin.rb
|
114
|
+
- lib/smart_proxy_monitoring_icinga2/plugin_configuration.rb
|
115
|
+
- settings.d/monitoring.yml.example
|
116
|
+
- settings.d/monitoring_icinga2.yml.example
|
117
|
+
homepage: http://github.com/theforeman/smart_proxy_monitoring
|
118
|
+
licenses:
|
119
|
+
- GPLv3
|
120
|
+
metadata: {}
|
121
|
+
post_install_message:
|
122
|
+
rdoc_options: []
|
123
|
+
require_paths:
|
124
|
+
- lib
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
requirements: []
|
136
|
+
rubyforge_project:
|
137
|
+
rubygems_version: 2.4.5
|
138
|
+
signing_key:
|
139
|
+
specification_version: 4
|
140
|
+
summary: Monitoring plug-in for Foreman's smart proxy
|
141
|
+
test_files: []
|
142
|
+
has_rdoc:
|