foreman_monitoring 0.0.1

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.
Files changed (36) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +31 -0
  4. data/Rakefile +47 -0
  5. data/app/controllers/api/v2/monitoring_results_controller.rb +29 -0
  6. data/app/helpers/concerns/foreman_monitoring/hosts_helper_ext.rb +46 -0
  7. data/app/lib/proxy_api/monitoring.rb +14 -0
  8. data/app/models/concerns/foreman_monitoring/host_extensions.rb +42 -0
  9. data/app/models/host_status/monitoring_status.rb +72 -0
  10. data/app/models/monitoring_result.rb +74 -0
  11. data/app/models/setting/monitoring.rb +16 -0
  12. data/app/overrides/add_host_monitoring_result_tab.rb +11 -0
  13. data/app/services/monitoring.rb +13 -0
  14. data/app/views/monitoring_results/_host_tab.html.erb +1 -0
  15. data/app/views/monitoring_results/_host_tab_pane.html.erb +25 -0
  16. data/config/routes.rb +10 -0
  17. data/db/migrate/20160817135723_create_monitoring_results.rb +12 -0
  18. data/db/seeds.d/60-monitoring_proxy_feature.rb +2 -0
  19. data/lib/foreman_monitoring/engine.rb +51 -0
  20. data/lib/foreman_monitoring/version.rb +3 -0
  21. data/lib/foreman_monitoring.rb +4 -0
  22. data/lib/tasks/foreman_monitoring_tasks.rake +35 -0
  23. data/locale/Makefile +62 -0
  24. data/locale/en/foreman_monitoring.po +19 -0
  25. data/locale/foreman_monitoring.pot +19 -0
  26. data/locale/gemspec.rb +2 -0
  27. data/test/factories/feature.rb +7 -0
  28. data/test/factories/host.rb +14 -0
  29. data/test/factories/monitoring_results.rb +30 -0
  30. data/test/factories/smart_proxy.rb +7 -0
  31. data/test/lib/proxy_api/monitoring_test.rb +22 -0
  32. data/test/test_plugin_helper.rb +24 -0
  33. data/test/unit/host_status/monitoring_status_test.rb +91 -0
  34. data/test/unit/host_test.rb +26 -0
  35. data/test/unit/monitoring_test.rb +17 -0
  36. metadata +115 -0
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 = 'ForemanMonitoring'
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
@@ -0,0 +1,29 @@
1
+ module Api
2
+ module V2
3
+ class MonitoringResultsController < V2::BaseController
4
+ include Api::Version2
5
+ include Foreman::Controller::SmartProxyAuth
6
+
7
+ add_smart_proxy_filters :create, :features => 'Monitoring'
8
+
9
+ def create
10
+ begin
11
+ MonitoringResult.import(monitoring_result_params.with_indifferent_access)
12
+ rescue => e
13
+ logger.error "Failed to import monitoring result: #{e.message}"
14
+ logger.debug e.backtrace.join("\n")
15
+ render :json => { 'message' => e.message }, :status => :unprocessable_entity
16
+ return
17
+ end
18
+
19
+ render :json => { 'message' => 'OK' }
20
+ end
21
+
22
+ private
23
+
24
+ def monitoring_result_params
25
+ params.permit(:host, :result, :service, :acknowledged, :downtime, :timestamp, :initial)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,46 @@
1
+ module ForemanMonitoring
2
+ module HostsHelperExt
3
+ extend ActiveSupport::Concern
4
+
5
+ # included do
6
+ # alias_method_chain :host_title_actions, :monitoring
7
+ # end
8
+
9
+ # def host_title_actions_with_monitoring(host)
10
+ # title_actions(
11
+ # button_group(
12
+ # link_to(_('Monitoring'), monitoring_show_host_path(host), :target => '_blank', :class => 'btn btn-default')
13
+ # )
14
+ # )
15
+ # host_title_actions_without_monitoring(host)
16
+ # end
17
+
18
+ def host_monitoring_result_icon_class(result)
19
+ icon_class = case result
20
+ when :ok
21
+ 'pficon-ok'
22
+ when :warning
23
+ 'pficon-info'
24
+ when :critical
25
+ 'pficon-error-circle-o'
26
+ else
27
+ 'pficon-help'
28
+ end
29
+
30
+ "host-status #{icon_class} #{host_monitoring_result_class(result)}"
31
+ end
32
+
33
+ def host_monitoring_result_class(result)
34
+ case result
35
+ when :ok
36
+ 'status-ok'
37
+ when :warning
38
+ 'status-warn'
39
+ when :critical
40
+ 'status-error'
41
+ else
42
+ 'status-question'
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,14 @@
1
+ module ProxyAPI
2
+ class Monitoring < ProxyAPI::Resource
3
+ def initialize(args)
4
+ @url = args[:url] + '/monitoring'
5
+ super args
6
+ end
7
+
8
+ def create_host_downtime(host, args = {})
9
+ parse(post(args, "downtime/host/#{host}"))
10
+ rescue => e
11
+ raise ProxyException.new(url, e, N_('Unable to set downtime for %s') % host)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,42 @@
1
+ module ForemanMonitoring
2
+ module HostExtensions
3
+ extend ActiveSupport::Concern
4
+ included do
5
+ before_destroy :downtime_host_destroy
6
+ after_build :downtime_host_build
7
+
8
+ has_many :monitoring_results, :foreign_key => 'host_id'
9
+ end
10
+
11
+ def monitoring_status(options = {})
12
+ @monitoring_status ||= get_status(HostStatus::MonitoringStatus).to_status(options)
13
+ end
14
+
15
+ def monitoring_status_label(options = {})
16
+ @monitoring_status_label ||= get_status(HostStatus::MonitoringStatus).to_label(options)
17
+ end
18
+
19
+ def refresh_monitoring_status
20
+ get_status(HostStatus::MonitoringStatus).refresh
21
+ end
22
+
23
+ def downtime_host_build
24
+ downtime_host(:comment => _('Host rebuilt in Foreman'))
25
+ end
26
+
27
+ def downtime_host_destroy
28
+ downtime_host(:comment => _('Host deleted in Foreman'))
29
+ end
30
+
31
+ def downtime_host(options)
32
+ return unless monitoring_results.any?
33
+ begin
34
+ monitoring = Monitoring.new
35
+ monitoring.set_downtime_host(self, options)
36
+ rescue ProxyAPI::ProxyException => e
37
+ errors.add(:base, _("Error setting downtime: '%s'") % e.message)
38
+ end
39
+ errors.empty?
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,72 @@
1
+ module HostStatus
2
+ class MonitoringStatus < HostStatus::Status
3
+ OK = 0
4
+ WARNING = 1
5
+ CRITICAL = 2
6
+ UNKNOWN = 3
7
+
8
+ def relevant?(_options = {})
9
+ host_not_in_build? && host_known_in_monitoring?
10
+ end
11
+
12
+ def to_status(_options = {})
13
+ state = OK
14
+ grouped_results.each do |resultset, _count|
15
+ result, downtime, acknowledged = resultset
16
+ next if downtime
17
+ result = WARNING if acknowledged || result == UNKNOWN
18
+ state = result if result > state
19
+ end
20
+ state
21
+ end
22
+
23
+ def to_global(_options = {})
24
+ return HostStatus::Global::OK unless should_affect_global_status?
25
+ case status
26
+ when OK
27
+ HostStatus::Global::OK
28
+ when WARNING
29
+ HostStatus::Global::WARN
30
+ when CRITICAL
31
+ HostStatus::Global::ERROR
32
+ else
33
+ HostStatus::Global::WARN
34
+ end
35
+ end
36
+
37
+ def self.status_name
38
+ N_('Monitoring Status')
39
+ end
40
+
41
+ def to_label(_options = {})
42
+ case status
43
+ when OK
44
+ N_('OK')
45
+ when WARNING
46
+ N_('Warning')
47
+ when CRITICAL
48
+ N_('Critical')
49
+ else
50
+ N_('Unknown')
51
+ end
52
+ end
53
+
54
+ def host_not_in_build?
55
+ host && !host.build
56
+ end
57
+
58
+ def host_known_in_monitoring?
59
+ host.monitoring_results.any?
60
+ end
61
+
62
+ def should_affect_global_status?
63
+ Setting[:monitoring_affect_global_status]
64
+ end
65
+
66
+ private
67
+
68
+ def grouped_results
69
+ host.monitoring_results.group([:result, :downtime, :acknowledged]).count
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,74 @@
1
+ class MonitoringResult < ActiveRecord::Base
2
+ enum :result => [:ok, :warning, :critical, :unknown]
3
+
4
+ belongs_to_host
5
+
6
+ def self.import(result)
7
+ host = Host.find_by_name(result[:host])
8
+
9
+ if host.nil?
10
+ logger.error "Unable to find host #{result[:host]}"
11
+ return false
12
+ end
13
+
14
+ start_time = Time.now.utc
15
+ logger.info "Processing monitoring result for #{host}"
16
+
17
+ updates = {
18
+ :result => result[:result],
19
+ :acknowledged => result[:acknowledged],
20
+ :downtime => result[:downtime],
21
+ :timestamp => (Time.at(result[:timestamp]).utc rescue nil)
22
+ }.compact
23
+
24
+ if result[:initial] && result[:service] == 'Host Check'
25
+ logger.info "Removing all monitoring results for #{host} on initial import"
26
+ MonitoringResult.where(:host => host).destroy_all
27
+ end
28
+
29
+ created = MonitoringResult.where(:host => host, :service => result[:service]).first_or_create
30
+ if created.timestamp.blank? || updates[:timestamp].blank? || created.timestamp < updates[:timestamp]
31
+ created.update_attributes(updates)
32
+
33
+ if created.persisted?
34
+ logger.info("Imported monitoring result for #{host} in #{(Time.now.utc - start_time).round(2)} seconds")
35
+ host.refresh_statuses
36
+ end
37
+ else
38
+ logger.debug "Skipping monitoring result import for #{host} as it is older than what we have."
39
+ end
40
+ end
41
+
42
+ def status
43
+ return :ok if downtime
44
+ return :warning if acknowledged
45
+ result.to_sym
46
+ end
47
+
48
+ def to_label
49
+ label_mapper(status)
50
+ end
51
+
52
+ def to_full_label
53
+ options = []
54
+ options << _('acknowledged') if acknowledged
55
+ options << _('in downtime') if downtime
56
+ suffix = options.any? ? " (#{options.join(', ')})" : ''
57
+ "#{label_mapper(result.to_sym)}#{suffix}"
58
+ end
59
+
60
+ private
61
+
62
+ def label_mapper(value)
63
+ case value
64
+ when :ok
65
+ _('OK')
66
+ when :warning
67
+ _('Warning')
68
+ when :critical
69
+ _('Critical')
70
+ else
71
+ _('Unknown')
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,16 @@
1
+ class Setting
2
+ class Monitoring < ::Setting
3
+ def self.load_defaults
4
+ # Check the table exists
5
+ return unless super
6
+
7
+ Setting.transaction do
8
+ [
9
+ set('monitoring_affect_global_status',
10
+ _("Monitoring status will affect a host's global status when enabled"),
11
+ true, N_('Monitoring status should affect global status'))
12
+ ].compact.each { |s| create! s.update(:category => 'Setting::Monitoring') }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ Deface::Override.new(:virtual_path => 'hosts/show',
2
+ :name => 'add_monitoring_result_tab',
3
+ :insert_bottom => 'ul.nav-tabs',
4
+ :partial => 'monitoring_results/host_tab'
5
+ )
6
+
7
+ Deface::Override.new(:virtual_path => 'hosts/show',
8
+ :name => 'add_monitoring_result_tab_pane',
9
+ :insert_bottom => 'div.tab-content',
10
+ :partial => 'monitoring_results/host_tab_pane'
11
+ )
@@ -0,0 +1,13 @@
1
+ class Monitoring
2
+ delegate :logger, :to => :Rails
3
+ attr_reader :proxy, :proxy_api
4
+
5
+ def initialize
6
+ @proxy = SmartProxy.with_features('Monitoring').first
7
+ @proxy_api = ProxyAPI::Monitoring.new(:url => proxy.url)
8
+ end
9
+
10
+ def set_downtime_host(host, options = {})
11
+ proxy_api.create_host_downtime(host.fqdn, { :author => 'Foreman', :comment => 'triggered by Foreman' }.merge(options))
12
+ end
13
+ end
@@ -0,0 +1 @@
1
+ <li><a href="#monitoring" data-toggle="tab"><%= _("Monitoring") %></a></li>
@@ -0,0 +1,25 @@
1
+ <div class="tab-pane" id="monitoring">
2
+ <% if @host.monitoring_results.any? %>
3
+ <table class="table table-bordered table-striped">
4
+ <thead
5
+ <tr>
6
+ <th colspan="2">Monitoring</th>
7
+ </tr>
8
+ </thead>
9
+ <tbody>
10
+ <% @host.monitoring_results.order(:service).each do |result| %>
11
+ <tr>
12
+ <td>
13
+ <%= result.service %>
14
+ </td>
15
+ <td>
16
+ <span class="<%= host_monitoring_result_icon_class(result.status) %>" title="<%= result.to_label %>"></span> <%= result.to_full_label %>
17
+ </td>
18
+ </tr>
19
+ <% end %>
20
+ </tbody>
21
+ </table>
22
+ <% else %>
23
+ <div class="alert alert-success"> <%= _('No monitoring results for this host') %> </div>
24
+ <% end %>
25
+ </div>
data/config/routes.rb ADDED
@@ -0,0 +1,10 @@
1
+ Rails.application.routes.draw do
2
+ namespace :api, :defaults => { :format => 'json' } do
3
+ scope '(:apiv)', :module => :v2,
4
+ :defaults => { :apiv => 'v2' },
5
+ :apiv => /v1|v2/,
6
+ :constraints => ApiConstraints.new(:version => 2) do
7
+ resources :monitoring_results, :only => [:create]
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ class CreateMonitoringResults < ActiveRecord::Migration
2
+ def change
3
+ create_table :monitoring_results do |t|
4
+ t.references :host, :null => false
5
+ t.string :service, :null => false
6
+ t.integer :result, :default => 0, :null => false
7
+ t.boolean :downtime, :default => false, :null => false
8
+ t.boolean :acknowledged, :default => false, :null => false
9
+ t.datetime :timestamp
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,2 @@
1
+ f = Feature.where(:name => 'Monitoring').first_or_create
2
+ raise "Unable to create proxy feature: #{format_errors f}" if f.nil? || f.errors.any?
@@ -0,0 +1,51 @@
1
+ module ForemanMonitoring
2
+ class Engine < ::Rails::Engine
3
+ engine_name 'foreman_monitoring'
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
+ # Add any db migrations
12
+ initializer 'foreman_monitoring.load_app_instance_data' do |app|
13
+ ForemanMonitoring::Engine.paths['db/migrate'].existent.each do |path|
14
+ app.config.paths['db/migrate'] << path
15
+ end
16
+ end
17
+
18
+ initializer 'foreman_monitoring.load_default_settings',
19
+ :before => :load_config_initializers do |_app|
20
+ if begin
21
+ Setting.table_exists?
22
+ rescue
23
+ false
24
+ end
25
+ require_dependency File.expand_path('../../../app/models/setting/monitoring.rb', __FILE__)
26
+ end
27
+ end
28
+
29
+ initializer 'foreman_monitoring.register_plugin', :before => :finisher_hook do |_app|
30
+ Foreman::Plugin.register :foreman_monitoring do
31
+ requires_foreman '>= 1.11'
32
+ register_custom_status HostStatus::MonitoringStatus
33
+ end
34
+ end
35
+
36
+ config.to_prepare do
37
+ begin
38
+ Host::Managed.send :include, ForemanMonitoring::HostExtensions
39
+ HostsHelper.send(:include, ForemanMonitoring::HostsHelperExt)
40
+ rescue => e
41
+ Rails.logger.warn "ForemanMonitoring: skipping engine hook (#{e})"
42
+ end
43
+ end
44
+
45
+ initializer 'foreman_monitoring.register_gettext', after: :load_config_initializers do |_app|
46
+ locale_dir = File.join(File.expand_path('../../..', __FILE__), 'locale')
47
+ locale_domain = 'foreman_monitoring'
48
+ Foreman::Gettext::Support.add_text_domain locale_domain, locale_dir
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,3 @@
1
+ module ForemanMonitoring
2
+ VERSION = '0.0.1'.freeze
3
+ end
@@ -0,0 +1,4 @@
1
+ require 'foreman_monitoring/engine'
2
+
3
+ module ForemanMonitoring
4
+ end
@@ -0,0 +1,35 @@
1
+ # Tests
2
+ namespace :test do
3
+ desc 'Test ForemanMonitoring'
4
+ Rake::TestTask.new(:foreman_monitoring) 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
+ t.warning = false
10
+ end
11
+ end
12
+
13
+ namespace :foreman_monitoring do
14
+ task :rubocop do
15
+ begin
16
+ require 'rubocop/rake_task'
17
+ RuboCop::RakeTask.new(:rubocop_foreman_monitoring) do |task|
18
+ task.patterns = ["#{ForemanMonitoring::Engine.root}/app/**/*.rb",
19
+ "#{ForemanMonitoring::Engine.root}/lib/**/*.rb",
20
+ "#{ForemanMonitoring::Engine.root}/test/**/*.rb"]
21
+ end
22
+ rescue
23
+ puts 'Rubocop not loaded.'
24
+ end
25
+
26
+ Rake::Task['rubocop_foreman_monitoring'].invoke
27
+ end
28
+ end
29
+
30
+ Rake::Task[:test].enhance ['test:foreman_monitoring']
31
+
32
+ load 'tasks/jenkins.rake'
33
+ if Rake::Task.task_defined?(:'jenkins:unit')
34
+ Rake::Task['jenkins:unit'].enhance ['test:foreman_monitoring', 'foreman_monitoring:rubocop']
35
+ 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_monitoring
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_monitoring
2
+ #
3
+ # This file is distributed under the same license as foreman_monitoring.
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_monitoring
2
+ #
3
+ # This file is distributed under the same license as foreman_monitoring.
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
+
data/locale/gemspec.rb ADDED
@@ -0,0 +1,2 @@
1
+ # Matches foreman_monitoring.gemspec
2
+ _('Set a downtime for hosts after they are deleted in Foreman.')
@@ -0,0 +1,7 @@
1
+ FactoryGirl.modify do
2
+ factory :feature do
3
+ trait :monitoring do
4
+ name 'Monitoring'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ FactoryGirl.modify do
2
+ factory :host do
3
+ trait :with_monitoring_results do
4
+ transient do
5
+ monitoring_result_count 20
6
+ end
7
+ after(:create) do |host, evaluator|
8
+ evaluator.monitoring_result_count.times do
9
+ FactoryGirl.create(:monitoring_result, :host => host)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end