foreman_icinga 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+