├── lib ├── foreman_monitoring │ ├── version.rb │ └── engine.rb ├── foreman_monitoring.rb └── tasks │ └── foreman_monitoring_tasks.rake ├── Gemfile ├── locale ├── gemspec.rb ├── en │ └── foreman_monitoring.po ├── foreman_monitoring.pot └── Makefile ├── test ├── factories │ ├── feature.rb │ ├── smart_proxy.rb │ ├── host.rb │ └── monitoring_results.rb ├── test_plugin_helper.rb ├── unit │ ├── monitoring_test.rb │ ├── monitoring_result_test.rb │ ├── host_status │ │ └── monitoring_status_test.rb │ └── host_test.rb ├── lib │ └── proxy_api │ │ └── monitoring_test.rb ├── controllers │ └── api │ │ └── v2 │ │ └── downtime_controller_test.rb └── functional │ └── hosts_controller_test.rb ├── .gitignore ├── .tx └── config ├── db ├── seeds.d │ └── 60-monitoring_proxy_feature.rb └── migrate │ ├── 20221026065954_fix_monitoring_settings_category_to_dsl.rb │ ├── 201910180900_rename_downtime_host_permission.rb │ ├── 20161220201510_add_monitoring_proxy_id_to_host_and_hostgroup.rb │ └── 20160817135723_create_monitoring_results.rb ├── app ├── views │ ├── monitoring_results │ │ ├── _host_tab.html.erb │ │ └── _host_tab_pane.html.erb │ └── hosts │ │ ├── select_multiple_monitoring_proxy.html.erb │ │ ├── select_multiple_downtime.html.erb │ │ ├── _host_downtime_checkbox.html.erb │ │ ├── _downtime_fields.html.erb │ │ └── _set_host_downtime.html.erb ├── overrides │ ├── add_host_set_downtime_modal.rb │ ├── add_host_multiple_power_set_downtime_checkbox.rb │ └── add_host_monitoring_result_tab.rb ├── models │ ├── concerns │ │ ├── foreman_monitoring │ │ │ ├── hostgroup_extensions.rb │ │ │ └── host_extensions.rb │ │ └── orchestration │ │ │ └── monitoring.rb │ ├── host_status │ │ └── monitoring_status.rb │ └── monitoring_result.rb ├── controllers │ ├── api │ │ └── v2 │ │ │ ├── monitoring_results_controller.rb │ │ │ └── downtime_controller.rb │ └── concerns │ │ └── foreman_monitoring │ │ ├── find_host_by_client_cert.rb │ │ └── hosts_controller_extensions.rb ├── services │ └── monitoring.rb ├── lib │ └── proxy_api │ │ └── monitoring.rb └── helpers │ └── foreman_monitoring │ └── hosts_helper.rb ├── .github └── workflows │ └── ci.yml ├── foreman_monitoring.gemspec ├── config └── routes.rb ├── Rakefile ├── .rubocop.yml ├── README.md ├── .rubocop_todo.yml └── LICENSE /lib/foreman_monitoring/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module ForemanMonitoring 4 | VERSION = '3.4.0' 5 | end 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'http://rubygems.org' 4 | 5 | gemspec 6 | 7 | gem 'theforeman-rubocop', '~> 0.1.0' 8 | -------------------------------------------------------------------------------- /lib/foreman_monitoring.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'foreman_monitoring/engine' 4 | 5 | module ForemanMonitoring 6 | end 7 | -------------------------------------------------------------------------------- /locale/gemspec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Matches foreman_monitoring.gemspec 4 | _('Set a downtime for hosts after they are deleted in Foreman.') 5 | -------------------------------------------------------------------------------- /test/factories/feature.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.modify do 4 | factory :feature do 5 | trait :monitoring do 6 | name { 'Monitoring' } 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle/ 2 | log/*.log 3 | pkg/ 4 | test/dummy/db/*.sqlite3 5 | test/dummy/log/*.log 6 | test/dummy/tmp/ 7 | test/dummy/.sass-cache 8 | locale/*.mo 9 | locale/*/*.pox 10 | Gemfile.lock 11 | .idea/ 12 | -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | 4 | [foreman.foreman_monitoring] 5 | file_filter = locale//foreman_monitoring.po 6 | source_file = locale/foreman_monitoring.pot 7 | source_lang = en 8 | type = PO 9 | -------------------------------------------------------------------------------- /db/seeds.d/60-monitoring_proxy_feature.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | f = Feature.where(:name => 'Monitoring').first_or_create 4 | raise "Unable to create proxy feature: #{format_errors f}" if f.nil? || f.errors.any? 5 | -------------------------------------------------------------------------------- /app/views/monitoring_results/_host_tab.html.erb: -------------------------------------------------------------------------------- 1 | <%- if authorized_for(:permission => 'view_monitoring_results', :auth_object => @host) && @host.monitored? -%> 2 |
  • <%= _("Monitoring") %>
  • 3 | <%- end -%> 4 | -------------------------------------------------------------------------------- /test/factories/smart_proxy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.modify do 4 | factory :smart_proxy do 5 | trait :monitoring do 6 | features { |sp| [sp.association(:feature, :monitoring)] } 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/views/hosts/select_multiple_monitoring_proxy.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'selected_hosts', :hosts => @hosts %> 2 | 3 | <%= form_for :proxy, :url => update_multiple_monitoring_proxy_hosts_path(:host_ids => params[:host_ids]) do |f| %> 4 | <%= multiple_proxy_select(f, 'Monitoring') %> 5 | <% end %> 6 | -------------------------------------------------------------------------------- /app/views/hosts/select_multiple_downtime.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'selected_hosts', :hosts => @hosts %> 2 | 3 | <%= form_for :downtime, :url => update_multiple_downtime_hosts_path(:host_ids => params[:host_ids]) do |f| %> 4 | <%= render :partial => 'downtime_fields', :locals => { :f => f } %> 5 | <% end %> 6 | -------------------------------------------------------------------------------- /app/views/hosts/_host_downtime_checkbox.html.erb: -------------------------------------------------------------------------------- 1 | <% if authorized_for(:controller => :hosts, :action => :select_multiple_downtime) %> 2 | <%= checkbox_f f, :set_downtime, { 3 | :label_size => 'col-md-6', 4 | :help_inline => _('Set a downtime for this host') 5 | }, 6 | 'true', 7 | 'false' %> 8 | <% end %> 9 | -------------------------------------------------------------------------------- /app/overrides/add_host_set_downtime_modal.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Deface::Override.new(:virtual_path => 'hosts/show', 4 | :name => 'add_monitoring_set_downtime_modal', 5 | :insert_after => 'div#review_before_build', 6 | :partial => 'hosts/set_host_downtime') 7 | -------------------------------------------------------------------------------- /db/migrate/20221026065954_fix_monitoring_settings_category_to_dsl.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class FixMonitoringSettingsCategoryToDsl < ActiveRecord::Migration[6.0] 4 | def up 5 | Setting.where(category: 'Setting::Monitoring').update_all(category: 'Setting') if column_exists?(:settings, :category) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/overrides/add_host_multiple_power_set_downtime_checkbox.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Deface::Override.new(:virtual_path => 'hosts/select_multiple_power_state', 4 | :name => 'add_host_multiple_power_set_downtime_checkbox', 5 | :insert_before => "erb[silent]:contains('end')", 6 | :partial => 'hosts/host_downtime_checkbox') 7 | -------------------------------------------------------------------------------- /db/migrate/201910180900_rename_downtime_host_permission.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class RenameDowntimeHostPermission < ActiveRecord::Migration[5.2] 4 | def up 5 | Permission.where(name: 'manage_host_downtimes').update_all(name: 'manage_downtime_hosts') if table_exists?(:permissions) 6 | end 7 | 8 | def down 9 | Permission.where(name: 'manage_downtime_hosts').update_all(name: 'manage_host_downtimes') if table_exists?(:permissions) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20161220201510_add_monitoring_proxy_id_to_host_and_hostgroup.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class AddMonitoringProxyIdToHostAndHostgroup < ActiveRecord::Migration[4.2] 4 | def self.up 5 | add_column :hosts, :monitoring_proxy_id, :integer 6 | add_column :hostgroups, :monitoring_proxy_id, :integer 7 | end 8 | 9 | def self.down 10 | remove_column :hosts, :monitoring_proxy_id 11 | remove_column :hostgroups, :monitoring_proxy_id 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/overrides/add_host_monitoring_result_tab.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Deface::Override.new(:virtual_path => 'hosts/show', 4 | :name => 'add_monitoring_result_tab', 5 | :insert_bottom => 'ul.nav-tabs', 6 | :partial => 'monitoring_results/host_tab') 7 | 8 | Deface::Override.new(:virtual_path => 'hosts/show', 9 | :name => 'add_monitoring_result_tab_pane', 10 | :insert_bottom => 'div.tab-content', 11 | :partial => 'monitoring_results/host_tab_pane') 12 | -------------------------------------------------------------------------------- /test/factories/host.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.modify do 4 | factory :host do 5 | trait :with_monitoring do 6 | monitoring_proxy do 7 | FactoryBot.create(:smart_proxy, :monitoring) 8 | end 9 | end 10 | 11 | trait :with_monitoring_results do 12 | transient do 13 | monitoring_result_count { 20 } 14 | end 15 | after(:create) do |host, evaluator| 16 | evaluator.monitoring_result_count.times do 17 | FactoryBot.create(:monitoring_result, :host => host) 18 | end 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /app/models/concerns/foreman_monitoring/hostgroup_extensions.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module ForemanMonitoring 4 | module HostgroupExtensions 5 | extend ActiveSupport::Concern 6 | 7 | def monitoring_proxy 8 | return super if ancestry.blank? 9 | 10 | SmartProxy.find_by(id: inherited_monitoring_proxy_id) 11 | end 12 | 13 | def inherited_monitoring_proxy_id 14 | return monitoring_proxy_id if ancestry.blank? 15 | 16 | self[:monitoring_proxy_id] || self.class.sort_by_ancestry(ancestors.where('monitoring_proxy_id is not NULL')).last.try(:monitoring_proxy_id) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /test/factories/monitoring_results.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :monitoring_result do 5 | sequence(:service) { |n| "Service #{n}" } 6 | result { rand(0..3) } 7 | 8 | trait :ok do 9 | result { 0 } 10 | end 11 | 12 | trait :warning do 13 | result { 1 } 14 | end 15 | 16 | trait :critical do 17 | result { 2 } 18 | end 19 | 20 | trait :unknown do 21 | result { 3 } 22 | end 23 | 24 | trait :downtime do 25 | downtime { true } 26 | end 27 | 28 | trait :acknowledged do 29 | acknowledged { true } 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /db/migrate/20160817135723_create_monitoring_results.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class CreateMonitoringResults < ActiveRecord::Migration[4.2] 4 | def change 5 | # rubocop:disable Rails/CreateTableWithTimestamps 6 | create_table :monitoring_results do |t| 7 | t.references :host, :null => false 8 | t.string :service, :null => false 9 | t.integer :result, :default => 0, :null => false 10 | t.boolean :downtime, :default => false, :null => false 11 | t.boolean :acknowledged, :default => false, :null => false 12 | t.datetime :timestamp 13 | end 14 | # rubocop:enable Rails/CreateTableWithTimestamps 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /locale/en/foreman_monitoring.po: -------------------------------------------------------------------------------- 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 \n" 13 | "Language-Team: Foreman Team \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 | 20 | -------------------------------------------------------------------------------- /locale/foreman_monitoring.pot: -------------------------------------------------------------------------------- 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 \n" 13 | "Language-Team: Foreman Team \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 | 20 | -------------------------------------------------------------------------------- /test/test_plugin_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # This calls the main test_helper in Foreman-core 4 | require 'test_helper' 5 | require 'database_cleaner' 6 | 7 | # Add plugin to FactoryBot's paths 8 | FactoryBot.definition_file_paths << File.join(File.dirname(__FILE__), 'factories') 9 | FactoryBot.reload 10 | 11 | # Foreman's setup doesn't handle cleaning up for Minitest::Spec 12 | DatabaseCleaner.strategy = :transaction 13 | 14 | def disable_monitoring_orchestration 15 | ProxyAPI::Monitoring.any_instance.stubs(:query_host).returns({}) 16 | end 17 | 18 | class Minitest::Spec 19 | before :each do 20 | DatabaseCleaner.start 21 | end 22 | 23 | after :each do 24 | DatabaseCleaner.clean 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /app/views/hosts/_downtime_fields.html.erb: -------------------------------------------------------------------------------- 1 | <%= text_f f, :comment, :size => "col-md-5", :label => _('Comment'), :help_inline => _('Short description that explains why the downtime was set.'), :required => true %> 2 | <%= monitoring_datetime_f f, :starttime, :size => "col-md-5", :label => _('Starttime'), :help_inline => _('Time when the downtime should start.'), :min => DateTime.now, :value => Time.current, :required => true %> 3 | <%= monitoring_datetime_f f, :endtime, :size => "col-md-5", :label => _('Endtime'), :help_inline => _('Time when the downtime should end.'), :value => Time.current.advance(:hours => 2), :required => true %> 4 | <%= checkbox_f f, :all_services, :size => "col-md-5", :label => _('All services'), :help_inline => _("Set downtime for all host's services.") %> 5 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | 9 | concurrency: 10 | group: ${{ github.ref_name }}-${{ github.workflow }} 11 | cancel-in-progress: true 12 | 13 | jobs: 14 | rubocop: 15 | uses: theforeman/actions/.github/workflows/rubocop.yml@v0 16 | with: 17 | command: bundle exec rubocop 18 | 19 | test: 20 | name: Ruby 21 | needs: rubocop 22 | strategy: 23 | fail-fast: false 24 | matrix: 25 | foreman: 26 | - 'develop' 27 | - '3.14-stable' 28 | - '3.13-stable' 29 | uses: theforeman/actions/.github/workflows/foreman_plugin.yml@v0 30 | with: 31 | plugin: foreman_monitoring 32 | foreman_version: ${{ matrix.foreman }} 33 | -------------------------------------------------------------------------------- /app/views/hosts/_set_host_downtime.html.erb: -------------------------------------------------------------------------------- 1 |