foreman_icinga 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/app/helpers/concerns/foreman_icinga/hosts_helper_ext.rb +31 -0
- data/app/models/concerns/foreman_icinga/host_extensions.rb +67 -0
- data/app/models/host_status/icinga_status.rb +72 -0
- data/app/models/setting/icinga.rb +42 -0
- data/app/services/icinga.rb +84 -0
- data/lib/foreman_icinga.rb +3 -0
- data/lib/foreman_icinga/engine.rb +31 -0
- metadata +51 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f71e804e85b08f2b14fb7865f28325f96bb11efc
|
4
|
+
data.tar.gz: 98ee2bc7eb4d5cdb0af315574b5cb7ca49d438ec
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2e574aa8dd618d34755337bc9d9ac96bca00c3972973c402660044bbfeb25915b3101f22908a970b6fc7a88684f28b2e232b0d7cefe41ad3029b03f7f7513278
|
7
|
+
data.tar.gz: 672a244cdf704e100276b17d9ec1d25776b62cc7e5d4a72452e244579ecdefc7c439c6248139127f57c1ebaac3bab3223ccc5e1ae54ae6d500f03d016155f48d
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ForemanIcinga
|
2
|
+
module HostsHelperExt
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
alias_method_chain :host_title_actions, :icinga
|
7
|
+
end
|
8
|
+
|
9
|
+
def host_title_actions_with_icinga(host)
|
10
|
+
title_actions(
|
11
|
+
button_group(
|
12
|
+
link_to(_('Icinga'), icinga_show_host_path(host), :target => '_blank')
|
13
|
+
)
|
14
|
+
)
|
15
|
+
host_title_actions_without_icinga(host)
|
16
|
+
end
|
17
|
+
|
18
|
+
def icinga_show_host_path(host)
|
19
|
+
params = {
|
20
|
+
:host => host.name
|
21
|
+
}
|
22
|
+
icinga_url_for('monitoring/host/show', params)
|
23
|
+
end
|
24
|
+
|
25
|
+
def icinga_url_for(route, params = {})
|
26
|
+
base = URI.join(Setting[:icinga_address], route).to_s
|
27
|
+
return base if params.empty?
|
28
|
+
base + '?' + params.to_query
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module ForemanIcinga
|
2
|
+
module HostExtensions
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
before_destroy :downtime_host
|
6
|
+
after_build :downtime_host
|
7
|
+
|
8
|
+
has_one :icinga_status_object, :class_name => 'HostStatus::IcingaStatus', :foreign_key => 'host_id'
|
9
|
+
|
10
|
+
scoped_search :in => :icinga_status_object, :on => :status, :rename => :icinga_status,
|
11
|
+
:complete_value => {
|
12
|
+
:ok => HostStatus::IcingaStatus::OK,
|
13
|
+
:warning => HostStatus::IcingaStatus::WARNING,
|
14
|
+
:critical => HostStatus::IcingaStatus::CRITICAL,
|
15
|
+
:unknown => HostStatus::IcingaStatus::UNKNOWN
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def icinga_status(options = {})
|
20
|
+
@icinga_status ||= get_status(HostStatus::IcingaStatus).to_status(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def icinga_status_label(options = {})
|
24
|
+
@icinga_status_label ||= get_status(HostStatus::IcingaStatus).to_label(options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def refresh_icinga_status
|
28
|
+
get_status(HostStatus::IcingaStatus).refresh
|
29
|
+
end
|
30
|
+
|
31
|
+
def downtime_host
|
32
|
+
logger.debug _('Setting downtime for host %s in Icinga') % name
|
33
|
+
return false unless icinga_configured?
|
34
|
+
return true unless icinga_enabled?
|
35
|
+
|
36
|
+
begin
|
37
|
+
icinga = Icinga.new
|
38
|
+
params = {
|
39
|
+
'host' => name,
|
40
|
+
'comment' => 'host deleted in foreman',
|
41
|
+
'duration' => '7200'
|
42
|
+
}
|
43
|
+
response = icinga.call('deployment/downtime/schedule', '', params)
|
44
|
+
errors.add(:base, _("Error from Icinga server: '%s'") % response['message']) if response['status'] == 'error'
|
45
|
+
|
46
|
+
rescue => error
|
47
|
+
message = _('Failed to set Icinga downtime for %s.') % name
|
48
|
+
errors.add(:base, message)
|
49
|
+
Foreman::Logging.exception(message, error)
|
50
|
+
end
|
51
|
+
errors.empty?
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def icinga_configured?
|
57
|
+
if icinga_enabled? && (Setting[:icinga_address].blank? || Setting[:icinga_token].blank?)
|
58
|
+
errors.add(:base, _('Icinga plugin is enabled but not configured. Please configure it before trying to delete a host.'))
|
59
|
+
end
|
60
|
+
errors.empty?
|
61
|
+
end
|
62
|
+
|
63
|
+
def icinga_enabled?
|
64
|
+
[true, 'true'].include? Setting[:icinga_enabled]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module HostStatus
|
2
|
+
class IcingaStatus < HostStatus::Status
|
3
|
+
OK = 0
|
4
|
+
WARNING = 1
|
5
|
+
CRITICAL = 2
|
6
|
+
UNKNOWN = 3
|
7
|
+
|
8
|
+
def relevant?
|
9
|
+
host_not_in_build? && host_known_in_icinga?
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_status(_options = {})
|
13
|
+
parse_host_status call_icinga
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_global(_options = {})
|
17
|
+
case self.status
|
18
|
+
when OK
|
19
|
+
HostStatus::Global::OK
|
20
|
+
when WARNING
|
21
|
+
HostStatus::Global::WARN
|
22
|
+
when CRITICAL
|
23
|
+
HostStatus::Global::ERROR
|
24
|
+
else
|
25
|
+
HostStatus::Global::OK
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.status_name
|
30
|
+
N_('Icinga Status')
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_label(_options = {})
|
34
|
+
case self.status
|
35
|
+
when OK
|
36
|
+
N_('OK')
|
37
|
+
when WARNING
|
38
|
+
N_('Warning')
|
39
|
+
when CRITICAL
|
40
|
+
N_('Critical')
|
41
|
+
else
|
42
|
+
N_('Unknown')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def host_not_in_build?
|
47
|
+
host && !host.build
|
48
|
+
end
|
49
|
+
|
50
|
+
def host_known_in_icinga?
|
51
|
+
true
|
52
|
+
end
|
53
|
+
|
54
|
+
def client
|
55
|
+
@icinga ||= Icinga.new
|
56
|
+
end
|
57
|
+
|
58
|
+
def call_icinga
|
59
|
+
client.call('deployment/health/check', '', {'host' => host.name})
|
60
|
+
end
|
61
|
+
|
62
|
+
def parse_host_status(response)
|
63
|
+
return UNKNOWN if response.key?('status') && response['status'] == 'error'
|
64
|
+
return UNKNOWN unless response.key?('healthy')
|
65
|
+
if response['healthy']
|
66
|
+
OK
|
67
|
+
else
|
68
|
+
WARNING
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class Setting::Icinga < ::Setting
|
2
|
+
BLANK_ATTRS << 'icinga_address'
|
3
|
+
BLANK_ATTRS << 'icinga_token'
|
4
|
+
|
5
|
+
def self.load_defaults
|
6
|
+
if SETTINGS[:icinga].present?
|
7
|
+
default_enabled = SETTINGS[:icinga][:enabled]
|
8
|
+
default_address = SETTINGS[:icinga][:address]
|
9
|
+
default_token = SETTINGS[:icinga][:token]
|
10
|
+
default_icinga_ssl_ca_file = SETTINGS[:icinga][:icinga_ssl_ca_file]
|
11
|
+
end
|
12
|
+
|
13
|
+
default_enabled = false if default_enabled.nil?
|
14
|
+
default_address ||= 'https://icingahost/icingaweb2/'
|
15
|
+
default_token ||= ''
|
16
|
+
default_icinga_ssl_ca_file ||= "#{SETTINGS[:puppetssldir]}/certs/ca.pem"
|
17
|
+
|
18
|
+
Setting.transaction do
|
19
|
+
[
|
20
|
+
set('icinga_enabled', _("Integration with Icingaweb2, enabled will set a downtime for a host when it's deleted in Foreman"), default_enabled)
|
21
|
+
].compact.each { |s| create s.update(:category => 'Setting::Icinga') }
|
22
|
+
end
|
23
|
+
|
24
|
+
Setting.transaction do
|
25
|
+
[
|
26
|
+
set('icinga_address', _('Foreman will send Icingaweb2 requests to this address'), default_address)
|
27
|
+
].compact.each { |s| create s.update(:category => 'Setting::Icinga') }
|
28
|
+
end
|
29
|
+
|
30
|
+
Setting.transaction do
|
31
|
+
[
|
32
|
+
set('icinga_token', _('Foreman will authenticate to icingaweb2 using this token'), default_token)
|
33
|
+
].compact.each { |s| create s.update(:category => 'Setting::Icinga') }
|
34
|
+
end
|
35
|
+
|
36
|
+
Setting.transaction do
|
37
|
+
[
|
38
|
+
set('icinga_ssl_ca_file', _('SSL CA file that Foreman will use to communicate with icinga'), default_icinga_ssl_ca_file)
|
39
|
+
].compact.each { |s| create s.update(:category => 'Setting::Icinga') }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
|
3
|
+
class Icinga
|
4
|
+
attr_reader :client, :token, :address
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@address = Setting[:icinga_address]
|
8
|
+
@token = Setting[:icinga_token]
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(endpoint, payload = '', params = {})
|
12
|
+
uri = icinga_url_for(endpoint, params.merge(default_params))
|
13
|
+
parse client(uri).post(payload)
|
14
|
+
rescue OpenSSL::SSL::SSLError => e
|
15
|
+
message = "SSL Connection to Icinga failed: #{e}"
|
16
|
+
logger.warn message
|
17
|
+
error_response message
|
18
|
+
end
|
19
|
+
|
20
|
+
def logger
|
21
|
+
Rails.logger
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
attr_reader :connect_params
|
27
|
+
|
28
|
+
def connect_params
|
29
|
+
{
|
30
|
+
:timeout => 3,
|
31
|
+
:open_timeout => 3,
|
32
|
+
:headers => {
|
33
|
+
:accept => :json
|
34
|
+
},
|
35
|
+
:verify_ssl => verify_ssl?,
|
36
|
+
:ssl_ca_file => ssl_ca_file
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def ssl_ca_file
|
41
|
+
Setting[:icinga_ssl_ca_file]
|
42
|
+
end
|
43
|
+
|
44
|
+
def verify_ssl?
|
45
|
+
OpenSSL::SSL::VERIFY_PEER
|
46
|
+
end
|
47
|
+
|
48
|
+
def default_params
|
49
|
+
{
|
50
|
+
'token' => token,
|
51
|
+
'json' => true
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def client(uri)
|
56
|
+
RestClient::Resource.new(uri, connect_params)
|
57
|
+
end
|
58
|
+
|
59
|
+
def parse(response)
|
60
|
+
if response && response.code >= 200 && response.code < 300
|
61
|
+
return response.body.present? ? JSON.parse(response.body) : error_response(_('received empty result'))
|
62
|
+
else
|
63
|
+
error_response "#{response.code} #{response.message}"
|
64
|
+
end
|
65
|
+
rescue JSON::ParserError => e
|
66
|
+
message = "Failed to parse icinga response: #{response} -> #{e}"
|
67
|
+
logger.warn message
|
68
|
+
error_response message
|
69
|
+
end
|
70
|
+
|
71
|
+
def error_response(message)
|
72
|
+
{
|
73
|
+
'status' => 'error',
|
74
|
+
'message' => message,
|
75
|
+
'success' => false
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def icinga_url_for(route, params = {})
|
80
|
+
base = URI.join(address, route).to_s
|
81
|
+
return base if params.empty?
|
82
|
+
base + '?' + params.to_query
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ForemanIcinga
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
engine_name 'foreman_icinga'
|
4
|
+
|
5
|
+
config.autoload_paths += Dir["#{config.root}/app/controllers/concerns"]
|
6
|
+
config.autoload_paths += Dir["#{config.root}/app/helpers/concerns"]
|
7
|
+
config.autoload_paths += Dir["#{config.root}/app/models/concerns"]
|
8
|
+
config.autoload_paths += Dir["#{config.root}/app/overrides"]
|
9
|
+
config.autoload_paths += Dir["#{config.root}/app/services"]
|
10
|
+
|
11
|
+
initializer 'foreman_icinga.load_default_settings', :before => :load_config_initializers do |_app|
|
12
|
+
require_dependency File.expand_path('../../../app/models/setting/icinga.rb', __FILE__) if begin
|
13
|
+
Setting.table_exists?
|
14
|
+
rescue
|
15
|
+
(false)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
initializer 'foreman_icinga.register_plugin', :after => :finisher_hook do |_app|
|
20
|
+
Foreman::Plugin.register :foreman_icinga do
|
21
|
+
requires_foreman '>= 1.10'
|
22
|
+
register_custom_status HostStatus::IcingaStatus
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
config.to_prepare do
|
27
|
+
Host::Managed.send :include, ForemanIcinga::HostExtensions
|
28
|
+
HostsHelper.send(:include, ForemanIcinga::HostsHelperExt)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: foreman_icinga
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Timo Goebel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-21 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Set a downtime for hosts after they are deleted in Foreman.
|
14
|
+
email: timo.goebel@dm.de
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- app/helpers/concerns/foreman_icinga/hosts_helper_ext.rb
|
20
|
+
- app/models/concerns/foreman_icinga/host_extensions.rb
|
21
|
+
- app/models/host_status/icinga_status.rb
|
22
|
+
- app/models/setting/icinga.rb
|
23
|
+
- app/services/icinga.rb
|
24
|
+
- lib/foreman_icinga.rb
|
25
|
+
- lib/foreman_icinga/engine.rb
|
26
|
+
homepage: http://www.github.com/FILIADATAGmbH/foreman_icinga
|
27
|
+
licenses:
|
28
|
+
- GPL-3.0
|
29
|
+
metadata: {}
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubyforge_project:
|
46
|
+
rubygems_version: 2.4.5
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: This is a foreman plugin to interact with icingaweb2 deployment module.
|
50
|
+
test_files: []
|
51
|
+
has_rdoc:
|