smart_proxy_monitoring 0.0.1 → 0.1.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 +4 -4
- data/README.md +103 -7
- data/lib/smart_proxy_monitoring/monitoring_api.rb +51 -0
- data/lib/smart_proxy_monitoring/monitoring_plugin.rb +1 -0
- data/lib/smart_proxy_monitoring/version.rb +1 -1
- data/lib/smart_proxy_monitoring.rb +1 -0
- data/lib/smart_proxy_monitoring_icinga2/icinga2_api_observer.rb +2 -1
- data/lib/smart_proxy_monitoring_icinga2/icinga2_client.rb +3 -3
- data/lib/smart_proxy_monitoring_icinga2/icinga2_initial_importer.rb +4 -1
- data/lib/smart_proxy_monitoring_icinga2/icinga2_result_uploader.rb +2 -1
- data/lib/smart_proxy_monitoring_icinga2/monitoring_icinga2_main.rb +77 -2
- data/lib/smart_proxy_monitoring_icinga2/plugin_configuration.rb +1 -0
- data/lib/smart_proxy_monitoring_icinga2/tasks_common.rb +19 -0
- data/lib/smart_proxy_monitoring_icingadirector/director_client.rb +95 -0
- data/lib/smart_proxy_monitoring_icingadirector/monitoring_icingadirector_main.rb +75 -0
- data/lib/smart_proxy_monitoring_icingadirector/monitoring_icingadirector_plugin.rb +13 -0
- data/lib/smart_proxy_monitoring_icingadirector/plugin_configuration.rb +12 -0
- data/lib/smart_proxy_monitoring_icingadirector.rb +2 -0
- data/settings.d/monitoring.yml.example +7 -1
- data/settings.d/monitoring_icinga2.yml.example +5 -3
- data/settings.d/monitoring_icingadirector.yml.example +14 -0
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 149d84b0fdd553512bd5ebd9570a688e96918579
|
4
|
+
data.tar.gz: b542c10c34d67dd7e0ebeea7fbf60b803be96a9f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b44ef5c7e691aea3a4dfd544cd9a686dc50731c1dfabdd6f0b1a3d78693a7ba03bf37faa283f2252434511ee73705e5073f2df115a2aef539011e83201f0b7c
|
7
|
+
data.tar.gz: 38ad6cb5b79d4e49bc8d9916c082aa83252060e5c241e60a5638c00e87529978fec9011d5923ee36390dc9a8f53f6f5b1e983252d8ea5360a6e97bcfb2c9a16a
|
data/README.md
CHANGED
@@ -18,7 +18,8 @@ This plug-in has not been packaged for Debian, yet.
|
|
18
18
|
# Configuration
|
19
19
|
|
20
20
|
The plug-in requires some configuration on the Monitoring server and the Smart Proxy.
|
21
|
-
For now the only supported Monitoring solution is Icinga 2
|
21
|
+
For now the only supported Monitoring solution is Icinga 2 and the combination of Icinga 2
|
22
|
+
and the Icinga Web 2 Module Director.
|
22
23
|
|
23
24
|
## Icinga 2
|
24
25
|
|
@@ -114,18 +115,40 @@ object ApiUser "foreman" {
|
|
114
115
|
# icinga2 pki sign-csr --csr /etc/icinga2/pki/foreman.csr --cert /etc/icinga2/pki/foreman.crt
|
115
116
|
```
|
116
117
|
|
118
|
+
In addition to the authentication a Host template is required. By default it uses "foreman-host" if none
|
119
|
+
is provided from the Foreman WebUI. This template should define defaults for the host check and intervals.
|
120
|
+
|
121
|
+
```
|
122
|
+
# vi /etc/icinga2/conf.d/templates.conf
|
123
|
+
template Host "foreman-host" {
|
124
|
+
check_command = "hostalive"
|
125
|
+
max_check_attempts = "3"
|
126
|
+
check_interval = 5m
|
127
|
+
retry_interval = 1m
|
128
|
+
enable_notifications = true
|
129
|
+
enable_active_checks = true
|
130
|
+
enable_passive_checks = true
|
131
|
+
enable_event_handler = true
|
132
|
+
enable_perfdata = true
|
133
|
+
volatile = false
|
134
|
+
}
|
135
|
+
```
|
136
|
+
|
117
137
|
### Smart Proxy
|
118
138
|
|
119
139
|
Ensure that the Monitoring module is enabled and uses the provider monitoring_icinga2.
|
120
140
|
It is the default provider so also no setting for use_provider is fine.
|
121
141
|
If you configured hosts in Icinga2 only with hostname instead of FQDN, you can add `:strip_domain` with
|
122
142
|
all the parts to strip, e.g. `.localdomain`.
|
143
|
+
By default, SmartProxy will collect monitoring statuses from your monitoring solution and upload them to
|
144
|
+
Foreman. This can be disabled by setting `collect_status` to `false`.
|
123
145
|
|
124
146
|
```
|
125
147
|
# vi /etc/foreman-proxy/settings.d/monitoring.yaml
|
126
148
|
---
|
127
149
|
:enabled: true
|
128
150
|
:use_provider: monitoring_icinga2
|
151
|
+
:collect_status: true
|
129
152
|
```
|
130
153
|
|
131
154
|
Configure the provider with your server details and the API User information.
|
@@ -138,23 +161,96 @@ instead of the FQDN of the server, you will have to set verify_ssl to false.
|
|
138
161
|
---
|
139
162
|
:enabled: true
|
140
163
|
:server: icinga2.localdomain
|
141
|
-
:api_cacert: /
|
164
|
+
:api_cacert: /etc/foreman-proxy/monitoring/ca.crt
|
165
|
+
#:api_port: 5665
|
142
166
|
:api_user: foreman
|
143
|
-
:api_usercert: /
|
144
|
-
:api_userkey: /
|
167
|
+
:api_usercert: /etc/foreman-proxy/monitoring/foreman.crt
|
168
|
+
:api_userkey: /etc/foreman-proxy/monitoring/foreman.key
|
145
169
|
#:api_password: foreman
|
146
170
|
:verify_ssl: true
|
147
171
|
```
|
148
172
|
|
173
|
+
## Icinga 2 and Icinga Web 2 Module Director
|
149
174
|
|
150
|
-
|
175
|
+
This requires you to do the configuration steps above so
|
176
|
+
Downtimes could be send to and Status information could be
|
177
|
+
read from Icinga 2.
|
178
|
+
|
179
|
+
In addition you have to configure the provider Icingadirector
|
180
|
+
for managing hosts in the Icinga Web 2 Module Director.
|
181
|
+
|
182
|
+
### Icinga Web 2 Module Director
|
183
|
+
|
184
|
+
Using the API of the Icinga Web 2 Module Director requires
|
185
|
+
Authentication and Authorisation like it is described in its
|
186
|
+
[documentation](https://github.com/Icinga/icingaweb2-module-director/blob/master/doc/70-REST-API.md).
|
151
187
|
|
152
|
-
|
153
|
-
|
188
|
+
For the basic authentication of the webserver there are two
|
189
|
+
possible ways of configuration. If you already use basic auth
|
190
|
+
simply add a user and password to the authentication source.
|
191
|
+
If you do not want to add basic authentication you can configure
|
192
|
+
the webserver to auto login as a user depending on your source ip.
|
193
|
+
```
|
194
|
+
# vi /etc/httpd/conf.d/icingaweb2.conf
|
195
|
+
...
|
196
|
+
RewriteBase /icingaweb2/
|
197
|
+
RewriteCond %{REMOTE_ADDR} ^192\.168\.142\.3
|
198
|
+
RewriteRule ^(.*)$ - [E=REMOTE_USER:foreman]
|
199
|
+
...
|
200
|
+
```
|
201
|
+
|
202
|
+
In Icinga Web 2 you also have to add an authentication backend
|
203
|
+
"external".
|
204
|
+
```
|
205
|
+
# vi /etc/icingaweb2/authentication.ini
|
206
|
+
[External]
|
207
|
+
backend = "external"
|
208
|
+
```
|
209
|
+
|
210
|
+
Furthermore a role is required assigning permissions to your user.
|
211
|
+
```
|
212
|
+
# vi /etc/icingaweb2/roles.ini
|
213
|
+
[Foreman]
|
214
|
+
users = "foreman"
|
215
|
+
permissions = "module/director, director/api, director/*"
|
216
|
+
```
|
217
|
+
|
218
|
+
### Smart Proxy
|
219
|
+
|
220
|
+
Ensure that the Monitoring module is enabled and uses the provider monitoring_icinga2
|
221
|
+
and monitoring_icingadirector.
|
222
|
+
```
|
223
|
+
# vi /etc/foreman-proxy/settings.d/monitoring.yaml
|
224
|
+
---
|
225
|
+
:enabled: true
|
226
|
+
:use_provider:
|
227
|
+
- monitoring_icinga2
|
228
|
+
- monitoring_icingadirector
|
229
|
+
```
|
230
|
+
|
231
|
+
Configure the provider with the location of your director installation and
|
232
|
+
the User information if required. Using SSL with verification is recommended
|
233
|
+
but not required.
|
234
|
+
```
|
235
|
+
---
|
236
|
+
:enabled: true
|
237
|
+
|
238
|
+
:director_url: https://www.example.com/icingaweb2/director
|
239
|
+
:director_cacert: /etc/foreman-proxy/monitoring/ca.crt
|
240
|
+
:director_user: foreman
|
241
|
+
:director_password: foreman
|
242
|
+
:verify_ssl: true
|
243
|
+
```
|
244
|
+
|
245
|
+
# TODO
|
154
246
|
|
155
247
|
Provider Icinga2:
|
156
248
|
* Add endpoint and zone management for Icinga 2 as agent
|
157
249
|
|
250
|
+
Additional Providers:
|
251
|
+
* Zabbix
|
252
|
+
* OpenNMS
|
253
|
+
|
158
254
|
# Copyright
|
159
255
|
|
160
256
|
Copyright (c) 2016 The Foreman developers
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'sinatra'
|
2
2
|
require 'smart_proxy_monitoring/monitoring_plugin'
|
3
|
+
require 'json'
|
3
4
|
|
4
5
|
module Proxy::Monitoring
|
5
6
|
class Api < ::Sinatra::Base
|
@@ -11,10 +12,60 @@ module Proxy::Monitoring
|
|
11
12
|
authorize_with_trusted_hosts
|
12
13
|
authorize_with_ssl_client
|
13
14
|
|
15
|
+
get '/host/:host' do |host|
|
16
|
+
begin
|
17
|
+
validate_dns_name!(host)
|
18
|
+
host = strip_domain(host)
|
19
|
+
|
20
|
+
server.query_host(host).to_json
|
21
|
+
rescue Proxy::Monitoring::NotFound => e
|
22
|
+
log_halt 404, e
|
23
|
+
rescue Proxy::Monitoring::ConnectionError => e
|
24
|
+
log_halt 503, e
|
25
|
+
rescue Exception => e
|
26
|
+
log_halt 400, e
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
put '/host/:host' do |host|
|
31
|
+
begin
|
32
|
+
validate_dns_name!(host)
|
33
|
+
host = strip_domain(host)
|
34
|
+
attributes = params[:attributes]
|
35
|
+
logger.debug "Creating host #{host} object with attributes #{attributes.inspect}"
|
36
|
+
|
37
|
+
server.create_host(host, attributes)
|
38
|
+
rescue Proxy::Monitoring::NotFound => e
|
39
|
+
log_halt 404, e
|
40
|
+
rescue Proxy::Monitoring::ConnectionError => e
|
41
|
+
log_halt 503, e
|
42
|
+
rescue Exception => e
|
43
|
+
log_halt 400, e
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
post '/host/:host' do |host|
|
48
|
+
begin
|
49
|
+
validate_dns_name!(host)
|
50
|
+
host = strip_domain(host)
|
51
|
+
attributes = params[:attributes]
|
52
|
+
logger.debug "Updating host #{host} object with attributes #{attributes.inspect}"
|
53
|
+
|
54
|
+
server.update_host(host, attributes)
|
55
|
+
rescue Proxy::Monitoring::NotFound => e
|
56
|
+
log_halt 404, e
|
57
|
+
rescue Proxy::Monitoring::ConnectionError => e
|
58
|
+
log_halt 503, e
|
59
|
+
rescue Exception => e
|
60
|
+
log_halt 400, e
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
14
64
|
delete '/host/:host' do |host|
|
15
65
|
begin
|
16
66
|
validate_dns_name!(host)
|
17
67
|
host = strip_domain(host)
|
68
|
+
logger.debug "Removing host #{host} object"
|
18
69
|
|
19
70
|
server.remove_host(host)
|
20
71
|
rescue Proxy::Monitoring::NotFound => e
|
@@ -10,6 +10,7 @@ module Proxy::Monitoring
|
|
10
10
|
|
11
11
|
uses_provider
|
12
12
|
default_settings use_provider: 'monitoring_icinga2'
|
13
|
+
default_settings collect_status: true
|
13
14
|
|
14
15
|
http_rackup_path File.expand_path('monitoring_http_config.ru', File.expand_path('../', __FILE__))
|
15
16
|
https_rackup_path File.expand_path('monitoring_http_config.ru', File.expand_path('../', __FILE__))
|
@@ -6,6 +6,7 @@ module ::Proxy::Monitoring::Icinga2
|
|
6
6
|
class Icinga2ApiObserver
|
7
7
|
include ::Proxy::Log
|
8
8
|
include ::Proxy::Monitoring::Icinga2::Common
|
9
|
+
include TasksCommon
|
9
10
|
|
10
11
|
attr_reader :semaphore
|
11
12
|
|
@@ -53,7 +54,7 @@ module ::Proxy::Monitoring::Icinga2
|
|
53
54
|
ssl_socket.sysclose unless ssl_socket.nil?
|
54
55
|
end
|
55
56
|
|
56
|
-
def
|
57
|
+
def do_start
|
57
58
|
@thread = Thread.new { monitor }
|
58
59
|
@thread.abort_on_exception = true
|
59
60
|
@thread
|
@@ -33,7 +33,7 @@ module ::Proxy::Monitoring::Icinga2
|
|
33
33
|
options.merge!(auth_options)
|
34
34
|
|
35
35
|
RestClient::Resource.new(
|
36
|
-
|
36
|
+
[baseurl, request_url].join(''),
|
37
37
|
options
|
38
38
|
)
|
39
39
|
end
|
@@ -79,8 +79,8 @@ module ::Proxy::Monitoring::Icinga2
|
|
79
79
|
client(url).post(data)
|
80
80
|
end
|
81
81
|
|
82
|
-
def put(url)
|
83
|
-
client(url).put
|
82
|
+
def put(url, data)
|
83
|
+
client(url).put(data)
|
84
84
|
end
|
85
85
|
|
86
86
|
def delete(url)
|
@@ -5,6 +5,7 @@ require 'json'
|
|
5
5
|
module ::Proxy::Monitoring::Icinga2
|
6
6
|
class Icinga2InitialImporter
|
7
7
|
include ::Proxy::Log
|
8
|
+
include TasksCommon
|
8
9
|
|
9
10
|
def initialize(queue)
|
10
11
|
@queue = queue.queue
|
@@ -34,6 +35,7 @@ module ::Proxy::Monitoring::Icinga2
|
|
34
35
|
results = Icinga2Client.get('/objects/hosts?attrs=name&attrs=last_check_result&attrs=acknowledgement')
|
35
36
|
results = JSON.parse(results)
|
36
37
|
results['results'].each do |result|
|
38
|
+
next if result['attrs']['last_check_result'] == nil
|
37
39
|
parsed = {
|
38
40
|
host: result['attrs']['name'],
|
39
41
|
result: result['attrs']['last_check_result']['state'],
|
@@ -50,6 +52,7 @@ module ::Proxy::Monitoring::Icinga2
|
|
50
52
|
results = Icinga2Client.get('/objects/services?attrs=name&attrs=last_check_result&attrs=acknowledgement&attrs=host_name')
|
51
53
|
results = JSON.parse(results)
|
52
54
|
results['results'].each do |result|
|
55
|
+
next if result['attrs']['last_check_result'] == nil
|
53
56
|
parsed = {
|
54
57
|
host: result['attrs']['host_name'],
|
55
58
|
service: result['attrs']['name'],
|
@@ -79,7 +82,7 @@ module ::Proxy::Monitoring::Icinga2
|
|
79
82
|
end
|
80
83
|
end
|
81
84
|
|
82
|
-
def
|
85
|
+
def do_start
|
83
86
|
@thread = Thread.new { monitor }
|
84
87
|
@thread.abort_on_exception = true
|
85
88
|
@thread
|
@@ -10,6 +10,7 @@ module ::Proxy::Monitoring::Icinga2
|
|
10
10
|
class Icinga2ResultUploader
|
11
11
|
include ::Proxy::Log
|
12
12
|
include ::Proxy::Monitoring::Icinga2::Common
|
13
|
+
include TasksCommon
|
13
14
|
|
14
15
|
attr_reader :semaphore
|
15
16
|
|
@@ -68,7 +69,7 @@ module ::Proxy::Monitoring::Icinga2
|
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|
71
|
-
def
|
72
|
+
def do_start
|
72
73
|
@thread = Thread.new { upload }
|
73
74
|
@thread.abort_on_exception = true
|
74
75
|
@thread
|
@@ -1,9 +1,45 @@
|
|
1
|
+
require 'smart_proxy_monitoring_icinga2/icinga2_client'
|
2
|
+
|
1
3
|
module Proxy::Monitoring::Icinga2
|
2
4
|
class Provider < ::Proxy::Monitoring::Provider
|
3
5
|
include Proxy::Log
|
4
6
|
include Proxy::Util
|
5
7
|
|
6
|
-
|
8
|
+
ICINGA_HOST_ATTRS = %w(display_name address address6 templates)
|
9
|
+
|
10
|
+
ICINGA_ATTR_MAPPING = {
|
11
|
+
'ip' => 'address',
|
12
|
+
'ip6' => 'address6',
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
def query_host(host)
|
16
|
+
request_url = "/objects/hosts/#{host}?attrs=vars&attrs=address&attrs=address6&attrs=templates"
|
17
|
+
|
18
|
+
result = with_errorhandling("Query #{host}") do
|
19
|
+
Icinga2Client.get(request_url)
|
20
|
+
end
|
21
|
+
host_attributes(host, result['results'][0]['attrs'])
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_host(host, attributes)
|
25
|
+
request_url = "/objects/hosts/#{host}"
|
26
|
+
|
27
|
+
result = with_errorhandling("Create #{host}") do
|
28
|
+
Icinga2Client.put(request_url, host_data(attributes).to_json)
|
29
|
+
end
|
30
|
+
result.to_json
|
31
|
+
end
|
32
|
+
|
33
|
+
def update_host(host, attributes)
|
34
|
+
request_url = "/objects/hosts/#{host}"
|
35
|
+
|
36
|
+
result = with_errorhandling("Update #{host}") do
|
37
|
+
Icinga2Client.post(request_url, host_data(attributes).to_json)
|
38
|
+
end
|
39
|
+
result.to_json
|
40
|
+
end
|
41
|
+
|
42
|
+
def remove_host(host)
|
7
43
|
request_url = "/objects/hosts/#{host}?cascade=1"
|
8
44
|
|
9
45
|
result = with_errorhandling("Remove #{host}") do
|
@@ -40,10 +76,47 @@ module Proxy::Monitoring::Icinga2
|
|
40
76
|
|
41
77
|
private
|
42
78
|
|
79
|
+
def host_attributes(host, data)
|
80
|
+
attributes = {}
|
81
|
+
|
82
|
+
data['templates'].delete(host)
|
83
|
+
data.delete('templates') if data['templates'] == [ 'foreman-host' ]
|
84
|
+
if data['vars'].nil?
|
85
|
+
data.delete('vars')
|
86
|
+
else
|
87
|
+
data = data.merge(data.delete('vars'))
|
88
|
+
end
|
89
|
+
|
90
|
+
data.each do |key, value|
|
91
|
+
key = ICINGA_ATTR_MAPPING.invert[key] if ICINGA_ATTR_MAPPING.invert.key?(key)
|
92
|
+
attributes[key] = value
|
93
|
+
end
|
94
|
+
|
95
|
+
attributes
|
96
|
+
end
|
97
|
+
|
98
|
+
def host_data(attributes)
|
99
|
+
data = {}
|
100
|
+
|
101
|
+
data['templates'] = [ 'foreman-host' ] unless attributes.has_key?('templates')
|
102
|
+
data['attrs'] = {}
|
103
|
+
|
104
|
+
attributes.each do |key, value|
|
105
|
+
key = ICINGA_ATTR_MAPPING[key] if ICINGA_ATTR_MAPPING.key?(key)
|
106
|
+
key = "vars.#{key}" unless ICINGA_HOST_ATTRS.include?(key)
|
107
|
+
data['attrs'][key] = value
|
108
|
+
end
|
109
|
+
|
110
|
+
data
|
111
|
+
end
|
112
|
+
|
43
113
|
def with_errorhandling(action)
|
44
114
|
response = yield
|
45
115
|
logger.debug "Monitoring - Action successful: #{action}"
|
46
116
|
result = JSON.parse(response.body)
|
117
|
+
if result.key?('error') && result['status'] == "No objects found."
|
118
|
+
raise Proxy::Monitoring::NotFound.new("Icinga server at #{::Proxy::Monitoring::Icinga2::Plugin.settings.server} returned no objects found.")
|
119
|
+
end
|
47
120
|
unless result.key?('results')
|
48
121
|
logger.error "Invalid Icinga result or result with errors: #{result.inspect}"
|
49
122
|
raise Proxy::Monitoring::Error.new("Icinga server at #{::Proxy::Monitoring::Icinga2::Plugin.settings.server} returned an invalid result.")
|
@@ -51,12 +124,14 @@ module Proxy::Monitoring::Icinga2
|
|
51
124
|
unless result['results'].first
|
52
125
|
raise Proxy::Monitoring::NotFound.new("Icinga server at #{::Proxy::Monitoring::Icinga2::Plugin.settings.server} returned an empty result.")
|
53
126
|
end
|
54
|
-
if result['results'][0]['code'] != 200
|
127
|
+
if result['results'][0]['code'] && result['results'][0]['code'] != 200
|
55
128
|
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
129
|
end
|
57
130
|
result
|
58
131
|
rescue JSON::ParserError => e
|
59
132
|
raise Proxy::Monitoring::Error.new("Icinga server at #{::Proxy::Monitoring::Icinga2::Plugin.settings.server} returned invalid JSON: '#{e.message}'")
|
133
|
+
rescue RestClient::NotFound => e
|
134
|
+
raise Proxy::Monitoring::NotFound.new("Icinga server at #{::Proxy::Monitoring::Icinga2::Plugin.settings.server} returned: #{e.message}.")
|
60
135
|
rescue RestClient::Exception => e
|
61
136
|
raise Proxy::Monitoring::Error.new("Icinga server at #{::Proxy::Monitoring::Icinga2::Plugin.settings.server} returned an error: '#{e.response}'")
|
62
137
|
rescue Errno::ECONNREFUSED => e
|
@@ -4,6 +4,7 @@ module ::Proxy::Monitoring::Icinga2
|
|
4
4
|
require 'smart_proxy_monitoring_common/monitoring_common'
|
5
5
|
require 'smart_proxy_monitoring_icinga2/monitoring_icinga2_main'
|
6
6
|
require 'smart_proxy_monitoring_icinga2/monitoring_icinga2_common'
|
7
|
+
require 'smart_proxy_monitoring_icinga2/tasks_common'
|
7
8
|
require 'smart_proxy_monitoring_icinga2/icinga2_upload_queue'
|
8
9
|
require 'smart_proxy_monitoring_icinga2/icinga2_client'
|
9
10
|
require 'smart_proxy_monitoring_icinga2/icinga2_initial_importer'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ::Proxy::Monitoring::Icinga2
|
2
|
+
module TasksCommon
|
3
|
+
def start
|
4
|
+
if activated?
|
5
|
+
do_start
|
6
|
+
else
|
7
|
+
logger.info "Not starting #{action} because collect_status is disabled in settings."
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def action
|
12
|
+
self.class.name.split('::').last
|
13
|
+
end
|
14
|
+
|
15
|
+
def activated?
|
16
|
+
Proxy::Monitoring::Plugin.settings.collect_status
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module ::Proxy::Monitoring::IcingaDirector
|
5
|
+
class DirectorClient
|
6
|
+
include ::Proxy::Log
|
7
|
+
|
8
|
+
def self.instance
|
9
|
+
@instance ||= new
|
10
|
+
end
|
11
|
+
|
12
|
+
def client(url)
|
13
|
+
RestClient::Resource.new(
|
14
|
+
request_url(url),
|
15
|
+
request_options
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def request_url(url)
|
20
|
+
URI.join(baseurl, url).to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def get(url)
|
24
|
+
logger.debug "IcingaDirector: GET request to #{url}"
|
25
|
+
client(url).get.body
|
26
|
+
rescue RestClient::NotFound
|
27
|
+
raise Proxy::Monitoring::NotFound.new("Icinga Director returned not found for #{url}.")
|
28
|
+
end
|
29
|
+
|
30
|
+
def post(url, payload)
|
31
|
+
logger.debug "IcingaDirector: POST request to #{url} with payload: #{payload}"
|
32
|
+
client(url).post(payload).body
|
33
|
+
end
|
34
|
+
|
35
|
+
def put(url, payload)
|
36
|
+
logger.debug "IcingaDirector: PUT request to #{url} with payload: #{payload}"
|
37
|
+
client(url).put(payload).body
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete(url)
|
41
|
+
logger.debug "IcingaDirector: DELETE request to #{url}"
|
42
|
+
client(url).delete.body
|
43
|
+
rescue RestClient::NotFound
|
44
|
+
raise Proxy::Monitoring::NotFound.new("Icinga Director returned not found for #{url}.")
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def request_options
|
50
|
+
{
|
51
|
+
headers: request_headers,
|
52
|
+
ssl_ca_file: cacert,
|
53
|
+
verify_ssl: verify_ssl?
|
54
|
+
}.merge(auth_options)
|
55
|
+
end
|
56
|
+
|
57
|
+
def auth_options
|
58
|
+
return {} unless basic_auth?
|
59
|
+
{
|
60
|
+
user: user,
|
61
|
+
password: password,
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def basic_auth?
|
66
|
+
user && password
|
67
|
+
end
|
68
|
+
|
69
|
+
def request_headers
|
70
|
+
{
|
71
|
+
'Accept' => 'application/json'
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def baseurl
|
76
|
+
Proxy::Monitoring::IcingaDirector::Plugin.settings.director_url + '/'
|
77
|
+
end
|
78
|
+
|
79
|
+
def user
|
80
|
+
Proxy::Monitoring::IcingaDirector::Plugin.settings.director_user
|
81
|
+
end
|
82
|
+
|
83
|
+
def password
|
84
|
+
Proxy::Monitoring::IcingaDirector::Plugin.settings.director_password
|
85
|
+
end
|
86
|
+
|
87
|
+
def cacert
|
88
|
+
Proxy::Monitoring::IcingaDirector::Plugin.settings.director_cacert
|
89
|
+
end
|
90
|
+
|
91
|
+
def verify_ssl?
|
92
|
+
Proxy::Monitoring::Icinga2::Plugin.settings.verify_ssl
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'smart_proxy_monitoring_icinga2/monitoring_icinga2_main'
|
2
|
+
require 'smart_proxy_monitoring_icingadirector/director_client'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Proxy::Monitoring::IcingaDirector
|
6
|
+
class Provider < ::Proxy::Monitoring::Icinga2::Provider
|
7
|
+
def query_host(host)
|
8
|
+
response = client.get("host?name=#{host}")
|
9
|
+
parse_response(response)
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_host(host, attributes)
|
13
|
+
payload = host_payload(host, attributes)
|
14
|
+
check_templates_exist(payload[:imports])
|
15
|
+
client.post('host', payload.to_json)
|
16
|
+
end
|
17
|
+
|
18
|
+
def update_host(host, attributes)
|
19
|
+
payload = host_payload(host, attributes)
|
20
|
+
check_templates_exist(payload[:imports])
|
21
|
+
client.put("host?name=#{host}", payload.to_json)
|
22
|
+
rescue RestClient::NotModified
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
def remove_host(host)
|
27
|
+
client.delete("host?name=#{host}")
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def check_templates_exist(templates)
|
33
|
+
templates.each do |template|
|
34
|
+
raise "Template #{template} not found." unless template_exists?(template)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def template_exists?(template)
|
39
|
+
result = client.get("host?name=#{template}")
|
40
|
+
result = JSON.parse(result)
|
41
|
+
result['object_type'] == 'template'
|
42
|
+
rescue Proxy::Monitoring::NotFound
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
def host_payload(host, attributes)
|
47
|
+
{
|
48
|
+
:object_name => host,
|
49
|
+
:object_type => 'object',
|
50
|
+
:address => attributes.delete('ip'),
|
51
|
+
:address6 => attributes.delete('ip6'),
|
52
|
+
:imports => attributes.delete('templates') || ['foreman_host'],
|
53
|
+
:vars => attributes
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def parse_response(response)
|
58
|
+
response = JSON.parse(response)
|
59
|
+
ip = response.delete('address')
|
60
|
+
ip6 = response.delete('address6')
|
61
|
+
templates = response.delete('imports')
|
62
|
+
result = {
|
63
|
+
'ip' => ip,
|
64
|
+
'ip6' => ip6,
|
65
|
+
}
|
66
|
+
result.merge!('templates' => templates) if templates != ['foreman_host']
|
67
|
+
result.merge!(response['vars'] || {})
|
68
|
+
result
|
69
|
+
end
|
70
|
+
|
71
|
+
def client
|
72
|
+
DirectorClient.instance
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ::Proxy::Monitoring::IcingaDirector
|
2
|
+
class Plugin < ::Proxy::Provider
|
3
|
+
plugin :monitoring_icingadirector, ::Proxy::Monitoring::VERSION
|
4
|
+
|
5
|
+
default_settings verify_ssl: true
|
6
|
+
|
7
|
+
requires :monitoring, ::Proxy::Monitoring::VERSION
|
8
|
+
requires :monitoring_icinga2, ::Proxy::Monitoring::VERSION
|
9
|
+
|
10
|
+
load_classes ::Proxy::Monitoring::IcingaDirector::PluginConfiguration
|
11
|
+
load_dependency_injection_wirings ::Proxy::Monitoring::IcingaDirector::PluginConfiguration
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module ::Proxy::Monitoring::IcingaDirector
|
2
|
+
class PluginConfiguration
|
3
|
+
def load_classes
|
4
|
+
require 'smart_proxy_monitoring_common/monitoring_common'
|
5
|
+
require 'smart_proxy_monitoring_icingadirector/monitoring_icingadirector_main'
|
6
|
+
end
|
7
|
+
|
8
|
+
def load_dependency_injection_wirings(container_instance, settings)
|
9
|
+
container_instance.dependency :monitoring_provider, lambda { ::Proxy::Monitoring::IcingaDirector::Provider.new }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -4,8 +4,14 @@
|
|
4
4
|
|
5
5
|
# Valid providers:
|
6
6
|
# monitoring_icinga2 (Icinga 2 API, default)
|
7
|
-
|
7
|
+
# monitoring_icingadirector (icingaweb2-module-director, requires monitoring_icinga2 provider)
|
8
|
+
#:use_provider:
|
9
|
+
# - monitoring_icinga2
|
10
|
+
# - monitoring_icingadirector
|
8
11
|
|
9
12
|
# Strip this part of the domain when communicating with the Monitoring server
|
10
13
|
# and add it when communicating with Foreman
|
11
14
|
# :strip_domain: .localdomain
|
15
|
+
|
16
|
+
# Collect monitoring status information and forward them to foreman
|
17
|
+
:collect_status: true
|
@@ -5,12 +5,14 @@
|
|
5
5
|
# The FQDN or IP address of the Icinga 2 server (if using IP address also set verify_ssl to false)
|
6
6
|
:server: icinga2.localdomain
|
7
7
|
# The CA certificate used by Icinga 2 (typically located on the server at /etc/icinga2/pki/ca.crt)
|
8
|
-
:api_cacert: /
|
8
|
+
:api_cacert: /etc/foreman-proxy/monitoring/ca.crt
|
9
|
+
# The port of Icinga 2 API (default is 5665)
|
10
|
+
#:api_port: 5665
|
9
11
|
# The name of API User
|
10
12
|
:api_user: foreman
|
11
13
|
# The certificate issued on the client_cn attribute of the API User and the corresponding key
|
12
|
-
:api_usercert: /
|
13
|
-
:api_userkey: /
|
14
|
+
:api_usercert: /etc/foreman-proxy/monitoring/foreman.crt
|
15
|
+
:api_userkey: /etc/foreman-proxy/monitoring/foreman.key
|
14
16
|
# The password from the password attribute of the API User (if not using certificates)
|
15
17
|
#:api_password: foreman
|
16
18
|
# SSL Verfification mode (boolean value)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
---
|
2
|
+
# Manage hosts via icingaweb2-module-director provider
|
3
|
+
:enabled: true
|
4
|
+
|
5
|
+
# The URL of icinga director
|
6
|
+
:director_url: https://www.example.com/icingaweb2/director
|
7
|
+
# The CA certificate used by Icinga Director (see httpd conf)
|
8
|
+
:director_cacert: /etc/foreman-proxy/monitoring/ca.crt
|
9
|
+
# The name of API User
|
10
|
+
:director_user: foreman
|
11
|
+
# The password from the password attribute of the API User (if not using certificates)
|
12
|
+
:director_password: foreman
|
13
|
+
# SSL Verfification mode (boolean value)
|
14
|
+
:verify_ssl: true
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_proxy_monitoring
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Timo Goebel
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2017-04-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|
@@ -112,8 +112,15 @@ files:
|
|
112
112
|
- lib/smart_proxy_monitoring_icinga2/monitoring_icinga2_main.rb
|
113
113
|
- lib/smart_proxy_monitoring_icinga2/monitoring_icinga2_plugin.rb
|
114
114
|
- lib/smart_proxy_monitoring_icinga2/plugin_configuration.rb
|
115
|
+
- lib/smart_proxy_monitoring_icinga2/tasks_common.rb
|
116
|
+
- lib/smart_proxy_monitoring_icingadirector.rb
|
117
|
+
- lib/smart_proxy_monitoring_icingadirector/director_client.rb
|
118
|
+
- lib/smart_proxy_monitoring_icingadirector/monitoring_icingadirector_main.rb
|
119
|
+
- lib/smart_proxy_monitoring_icingadirector/monitoring_icingadirector_plugin.rb
|
120
|
+
- lib/smart_proxy_monitoring_icingadirector/plugin_configuration.rb
|
115
121
|
- settings.d/monitoring.yml.example
|
116
122
|
- settings.d/monitoring_icinga2.yml.example
|
123
|
+
- settings.d/monitoring_icingadirector.yml.example
|
117
124
|
homepage: http://github.com/theforeman/smart_proxy_monitoring
|
118
125
|
licenses:
|
119
126
|
- GPLv3
|
@@ -134,9 +141,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
141
|
version: '0'
|
135
142
|
requirements: []
|
136
143
|
rubyforge_project:
|
137
|
-
rubygems_version: 2.
|
144
|
+
rubygems_version: 2.6.11
|
138
145
|
signing_key:
|
139
146
|
specification_version: 4
|
140
147
|
summary: Monitoring plug-in for Foreman's smart proxy
|
141
148
|
test_files: []
|
142
|
-
has_rdoc:
|