foreman_icinga 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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,3 @@
1
+ module ForemanIcinga
2
+ require 'foreman_icinga/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
3
+ 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: