foreman_icinga 0.0.3 → 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.
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # Foreman Icingaweb2 Plugin
2
+
3
+ This is a foreman plugin to interact with icingaweb2's [deployment module](https://github.com/Thomas-Gelf/icingaweb2-module-deployment).
4
+ At the moment it basically sets a downtime for a hosts that gets deleted in foreman.
5
+
6
+ This plugin is work in progress. It should work well, but is subject to a lot of major changes. Try it, report your feedback and contribute!
7
+
8
+ # Installation
9
+
10
+ See [How_to_Install_a_Plugin](http://projects.theforeman.org/projects/foreman/wiki/How_to_Install_a_Plugin)
11
+ for how to install Foreman plugins
12
+
13
+ # Usage
14
+
15
+ Go to Administer > Settings > Icinga and set `icinga_address` with your Icingaweb2 address, `icinga_enabled` to either true or false if you want to enable or disable Icingaweb2 integration. In addition you need to set `icinga_token` to an api token specified in the Icingaweb2 deployment module settings.
16
+
17
+ ## Contributing
18
+
19
+ Fork and send a Pull Request. Thanks!
20
+
21
+ # Copyright
22
+ Copyright 2015 FILIADATA GmbH, Germany
23
+
24
+ This program is free software: you can redistribute it and/or modify
25
+ it under the terms of the GNU General Public License as published by
26
+ the Free Software Foundation, either version 3 of the License, or
27
+ (at your option) any later version.
28
+
29
+ This program is distributed in the hope that it will be useful,
30
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
31
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32
+ GNU General Public License for more details.
33
+
34
+ You should have received a copy of the GNU General Public License
35
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'ForemanIcinga'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path('../test/dummy/Rakefile', __FILE__)
24
+
25
+ Bundler::GemHelper.install_tasks
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib'
31
+ t.libs << 'test'
32
+ t.pattern = 'test/**/*_test.rb'
33
+ t.verbose = false
34
+ end
35
+
36
+ task default: :test
37
+
38
+ begin
39
+ require 'rubocop/rake_task'
40
+ RuboCop::RakeTask.new
41
+ rescue => _
42
+ puts 'Rubocop not loaded.'
43
+ end
44
+
45
+ task :default do
46
+ Rake::Task['rubocop'].execute
47
+ end
@@ -41,21 +41,24 @@ module ForemanIcinga
41
41
  'duration' => '7200'
42
42
  }
43
43
  response = icinga.call('deployment/downtime/schedule', '', params)
44
- errors.add(:base, _("Error from Icinga server: '%s'") % response['message']) if response['status'] == 'error'
45
44
 
45
+ if response['status'] == 'error' && ! icinga_ignore_failed_action?
46
+ errors.add(:base, _("Error from Icinga server: '%s'") % response['message'])
47
+ end
46
48
  rescue => error
47
49
  message = _('Failed to set Icinga downtime for %s.') % name
48
- errors.add(:base, message)
50
+ errors.add(:base, message) unless icinga_ignore_failed_action?
49
51
  Foreman::Logging.exception(message, error)
50
52
  end
51
- errors.empty?
53
+ icinga_ignore_failed_action? || errors.empty?
52
54
  end
53
55
 
54
56
  private
55
57
 
56
58
  def icinga_configured?
57
59
  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.'))
60
+ errors.add(:base,
61
+ _('Icinga plugin is enabled but not configured. Please configure it before trying to delete a host.'))
59
62
  end
60
63
  errors.empty?
61
64
  end
@@ -63,5 +66,9 @@ module ForemanIcinga
63
66
  def icinga_enabled?
64
67
  [true, 'true'].include? Setting[:icinga_enabled]
65
68
  end
69
+
70
+ def icinga_ignore_failed_action?
71
+ [true, 'true'].include? Setting[:icinga_ignore_failed_action]
72
+ end
66
73
  end
67
74
  end
@@ -14,7 +14,8 @@ module HostStatus
14
14
  end
15
15
 
16
16
  def to_global(_options = {})
17
- case self.status
17
+ return HostStatus::Global::OK unless should_affect_global_status?
18
+ case status
18
19
  when OK
19
20
  HostStatus::Global::OK
20
21
  when WARNING
@@ -31,7 +32,7 @@ module HostStatus
31
32
  end
32
33
 
33
34
  def to_label(_options = {})
34
- case self.status
35
+ case status
35
36
  when OK
36
37
  N_('OK')
37
38
  when WARNING
@@ -51,12 +52,16 @@ module HostStatus
51
52
  true
52
53
  end
53
54
 
55
+ def should_affect_global_status?
56
+ Setting[:icinga_affect_global_status]
57
+ end
58
+
54
59
  def client
55
60
  @icinga ||= Icinga.new
56
61
  end
57
62
 
58
63
  def call_icinga
59
- client.call('deployment/health/check', '', {'host' => host.name})
64
+ client.call('deployment/health/check', '', 'host' => host.name)
60
65
  end
61
66
 
62
67
  def parse_host_status(response)
@@ -1,42 +1,39 @@
1
- class Setting::Icinga < ::Setting
2
- BLANK_ATTRS << 'icinga_address'
3
- BLANK_ATTRS << 'icinga_token'
1
+ class Setting
2
+ class Icinga < ::Setting
3
+ BLANK_ATTRS << 'icinga_address'
4
+ BLANK_ATTRS << 'icinga_token'
4
5
 
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
6
+ def self.load_defaults
7
+ # Check the table exists
8
+ return unless super
12
9
 
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"
10
+ Setting.transaction do
11
+ [
12
+ set('icinga_enabled',
13
+ _("Integration with Icingaweb2, enabled will set a downtime for a host when it's deleted in Foreman"),
14
+ false, N_('Icinga enabled?')),
17
15
 
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
16
+ set('icinga_address',
17
+ _('Foreman will send Icingaweb2 requests to this address'),
18
+ 'https://icingahost/icingaweb2/', N_('Icinga address')),
23
19
 
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
20
+ set('icinga_token',
21
+ _('Foreman will authenticate to icingaweb2 using this token'),
22
+ '', N_('Icinga Token')),
29
23
 
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
24
+ set('icinga_ssl_ca_file',
25
+ _('SSL CA file that Foreman will use to communicate with icinga'),
26
+ "#{SETTINGS[:puppetssldir]}/certs/ca.pem", N_('Icinga SSL CA file')),
27
+
28
+ set('icinga_affect_global_status',
29
+ _("Icinga status will affect a host's global status when enabled"),
30
+ true, N_('Icinga should affect global status')),
35
31
 
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') }
32
+ set('icinga_ignore_failed_action',
33
+ _("Host will be deleted in Foreman even though Foreman was unable to set a downtime in Icinga"),
34
+ false, N_('Ignore failed icinga requests'))
35
+ ].compact.each { |s| create! s.update(:category => 'Setting::Icinga') }
36
+ end
40
37
  end
41
38
  end
42
39
  end
@@ -10,7 +10,7 @@ class Icinga
10
10
 
11
11
  def call(endpoint, payload = '', params = {})
12
12
  uri = icinga_url_for(endpoint, params.merge(default_params))
13
- parse client(uri).post(payload)
13
+ parse post(uri, payload)
14
14
  rescue OpenSSL::SSL::SSLError => e
15
15
  message = "SSL Connection to Icinga failed: #{e}"
16
16
  logger.warn message
@@ -56,6 +56,10 @@ class Icinga
56
56
  RestClient::Resource.new(uri, connect_params)
57
57
  end
58
58
 
59
+ def post(path, payload = '')
60
+ client(path).post(payload)
61
+ end
62
+
59
63
  def parse(response)
60
64
  if response && response.code >= 200 && response.code < 300
61
65
  return response.body.present? ? JSON.parse(response.body) : error_response(_('received empty result'))
@@ -1,3 +1,4 @@
1
+ require 'foreman_icinga/engine'
2
+
1
3
  module ForemanIcinga
2
- require 'foreman_icinga/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
3
4
  end
@@ -9,11 +9,13 @@ module ForemanIcinga
9
9
  config.autoload_paths += Dir["#{config.root}/app/services"]
10
10
 
11
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
12
+ if begin
13
+ Setting.table_exists?
14
+ rescue
15
+ false
16
+ end
17
+ require_dependency File.expand_path('../../../app/models/setting/icinga.rb', __FILE__)
18
+ end
17
19
  end
18
20
 
19
21
  initializer 'foreman_icinga.register_plugin', :after => :finisher_hook do |_app|
@@ -24,8 +26,18 @@ module ForemanIcinga
24
26
  end
25
27
 
26
28
  config.to_prepare do
27
- Host::Managed.send :include, ForemanIcinga::HostExtensions
28
- HostsHelper.send(:include, ForemanIcinga::HostsHelperExt)
29
+ begin
30
+ Host::Managed.send :include, ForemanIcinga::HostExtensions
31
+ HostsHelper.send(:include, ForemanIcinga::HostsHelperExt)
32
+ rescue => e
33
+ Rails.logger.warn "ForemanIcinga: skipping engine hook (#{e})"
34
+ end
35
+ end
36
+
37
+ initializer 'foreman_icinga.register_gettext', after: :load_config_initializers do |_app|
38
+ locale_dir = File.join(File.expand_path('../../..', __FILE__), 'locale')
39
+ locale_domain = 'foreman_icinga'
40
+ Foreman::Gettext::Support.add_text_domain locale_domain, locale_dir
29
41
  end
30
42
  end
31
43
  end
@@ -0,0 +1,3 @@
1
+ module ForemanIcinga
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,39 @@
1
+ # Tests
2
+ namespace :test do
3
+ desc 'Test ForemanIcinga'
4
+ Rake::TestTask.new(:foreman_icinga) do |t|
5
+ test_dir = File.join(File.dirname(__FILE__), '../..', 'test')
6
+ t.libs << ['test', test_dir]
7
+ t.pattern = "#{test_dir}/**/*_test.rb"
8
+ t.verbose = true
9
+ end
10
+ end
11
+
12
+ namespace :foreman_icinga do
13
+ task :rubocop do
14
+ begin
15
+ require 'rubocop/rake_task'
16
+ RuboCop::RakeTask.new(:rubocop_foreman_icinga) do |task|
17
+ task.patterns = ["#{ForemanIcinga::Engine.root}/app/**/*.rb",
18
+ "#{ForemanIcinga::Engine.root}/lib/**/*.rb",
19
+ "#{ForemanIcinga::Engine.root}/test/**/*.rb"]
20
+ end
21
+ rescue
22
+ puts 'Rubocop not loaded.'
23
+ end
24
+
25
+ Rake::Task['rubocop_foreman_icinga'].invoke
26
+ end
27
+ end
28
+
29
+ Rake::Task[:test].enhance do
30
+ Rake::Task['test:foreman_icinga'].invoke
31
+ end
32
+
33
+ load 'tasks/jenkins.rake'
34
+ if Rake::Task.task_defined?(:'jenkins:unit')
35
+ Rake::Task['jenkins:unit'].enhance do
36
+ Rake::Task['test:foreman_icinga'].invoke
37
+ Rake::Task['foreman_icinga:rubocop'].invoke
38
+ end
39
+ end
data/locale/Makefile ADDED
@@ -0,0 +1,62 @@
1
+ #
2
+ # Makefile for PO merging and MO generation. More info in the README.
3
+ #
4
+ # make all-mo (default) - generate MO files
5
+ # make check - check translations using translate-tool
6
+ # make tx-update - download and merge translations from Transifex
7
+ # make clean - clean everything
8
+ #
9
+ DOMAIN = foreman_icinga
10
+ VERSION = $(shell ruby -e 'require "rubygems";spec = Gem::Specification::load(Dir.glob("../*.gemspec")[0]);puts spec.version')
11
+ POTFILE = $(DOMAIN).pot
12
+ MOFILE = $(DOMAIN).mo
13
+ POFILES = $(shell find . -name '*.po')
14
+ MOFILES = $(patsubst %.po,%.mo,$(POFILES))
15
+ POXFILES = $(patsubst %.po,%.pox,$(POFILES))
16
+
17
+ %.mo: %.po
18
+ mkdir -p $(shell dirname $@)/LC_MESSAGES
19
+ msgfmt -o $(shell dirname $@)/LC_MESSAGES/$(MOFILE) $<
20
+
21
+ # Generate MO files from PO files
22
+ all-mo: $(MOFILES)
23
+
24
+ # Check for malformed strings
25
+ %.pox: %.po
26
+ msgfmt -c $<
27
+ pofilter --nofuzzy -t variables -t blank -t urls -t emails -t long -t newlines \
28
+ -t endwhitespace -t endpunc -t puncspacing -t options -t printf -t validchars --gnome $< > $@
29
+ cat $@
30
+ ! grep -q msgid $@
31
+
32
+ check: $(POXFILES)
33
+ msgfmt -c ${POTFILE}
34
+
35
+ # Merge PO files
36
+ update-po:
37
+ for f in $(shell find ./ -name "*.po") ; do \
38
+ msgmerge -N --backup=none -U $$f ${POTFILE} ; \
39
+ done
40
+
41
+ # Unify duplicate translations
42
+ uniq-po:
43
+ for f in $(shell find ./ -name "*.po") ; do \
44
+ msguniq $$f -o $$f ; \
45
+ done
46
+
47
+ tx-pull:
48
+ tx pull -f
49
+ for f in $(POFILES) ; do \
50
+ sed -i 's/^\("Project-Id-Version: \).*$$/\1$(DOMAIN) $(VERSION)\\n"/' $$f; \
51
+ done
52
+ -git commit -a -m "i18n - pulling from tx"
53
+
54
+ reset-po:
55
+ # merging po files is unnecessary when using transifex.com
56
+ git checkout -- ../locale/*/*po
57
+
58
+ tx-update: tx-pull reset-po $(MOFILES)
59
+ # amend mo files
60
+ git add ../locale/*/LC_MESSAGES
61
+ git commit -a --amend -m "i18n - pulling from tx"
62
+ -echo Changes commited!
@@ -0,0 +1,19 @@
1
+ # foreman_icinga
2
+ #
3
+ # This file is distributed under the same license as foreman_icinga.
4
+ #
5
+ #, fuzzy
6
+ msgid ""
7
+ msgstr ""
8
+ "Project-Id-Version: version 0.0.1\n"
9
+ "Report-Msgid-Bugs-To: \n"
10
+ "POT-Creation-Date: 2014-08-20 08:46+0100\n"
11
+ "PO-Revision-Date: 2014-08-20 08:54+0100\n"
12
+ "Last-Translator: Foreman Team <foreman-dev@googlegroups.com>\n"
13
+ "Language-Team: Foreman Team <foreman-dev@googlegroups.com>\n"
14
+ "Language: \n"
15
+ "MIME-Version: 1.0\n"
16
+ "Content-Type: text/plain; charset=UTF-8\n"
17
+ "Content-Transfer-Encoding: 8bit\n"
18
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
19
+
@@ -0,0 +1,19 @@
1
+ # foreman_icinga
2
+ #
3
+ # This file is distributed under the same license as foreman_icinga.
4
+ #
5
+ #, fuzzy
6
+ msgid ""
7
+ msgstr ""
8
+ "Project-Id-Version: version 0.0.1\n"
9
+ "Report-Msgid-Bugs-To: \n"
10
+ "POT-Creation-Date: 2014-08-20 08:46+0100\n"
11
+ "PO-Revision-Date: 2014-08-20 08:46+0100\n"
12
+ "Last-Translator: Foreman Team <foreman-dev@googlegroups.com>\n"
13
+ "Language-Team: Foreman Team <foreman-dev@googlegroups.com>\n"
14
+ "Language: \n"
15
+ "MIME-Version: 1.0\n"
16
+ "Content-Type: text/plain; charset=UTF-8\n"
17
+ "Content-Transfer-Encoding: 8bit\n"
18
+ "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
19
+