foreman_icinga 0.0.3

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 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: