foreman_monitoring 1.0.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/api/v2/downtime_controller.rb +63 -0
- data/app/controllers/api/v2/monitoring_results_controller.rb +2 -0
- data/app/controllers/concerns/foreman_monitoring/find_host_by_client_cert.rb +59 -0
- data/app/controllers/concerns/foreman_monitoring/hosts_controller_extensions.rb +7 -5
- data/app/helpers/concerns/foreman_monitoring/hosts_helper_ext.rb +7 -5
- data/app/lib/proxy_api/monitoring.rb +3 -0
- data/app/models/concerns/foreman_monitoring/host_extensions.rb +4 -1
- data/app/models/concerns/foreman_monitoring/hostgroup_extensions.rb +4 -0
- data/app/models/concerns/orchestration/monitoring.rb +13 -4
- data/app/models/host_status/monitoring_status.rb +5 -0
- data/app/models/monitoring_result.rb +6 -3
- data/app/models/setting/monitoring.rb +2 -0
- data/app/overrides/add_host_monitoring_result_tab.rb +8 -6
- data/app/overrides/add_host_multiple_power_set_downtime_checkbox.rb +5 -3
- data/app/overrides/add_host_set_downtime_modal.rb +4 -2
- data/app/services/monitoring.rb +3 -0
- data/app/views/monitoring_results/_host_tab_pane.html.erb +1 -1
- data/config/routes.rb +3 -0
- data/db/migrate/20160817135723_create_monitoring_results.rb +2 -0
- data/db/migrate/20161220201510_add_monitoring_proxy_id_to_host_and_hostgroup.rb +2 -0
- data/db/migrate/201910180900_rename_downtime_host_permission.rb +15 -0
- data/db/seeds.d/60-monitoring_proxy_feature.rb +2 -0
- data/lib/foreman_monitoring.rb +2 -0
- data/lib/foreman_monitoring/engine.rb +26 -22
- data/lib/foreman_monitoring/version.rb +3 -1
- data/lib/tasks/foreman_monitoring_tasks.rake +3 -1
- data/locale/gemspec.rb +2 -0
- data/test/controllers/api/v2/downtime_controller_test.rb +73 -0
- data/test/factories/feature.rb +3 -1
- data/test/factories/host.rb +3 -1
- data/test/factories/monitoring_results.rb +8 -6
- data/test/factories/smart_proxy.rb +2 -0
- data/test/functional/hosts_controller_test.rb +18 -16
- data/test/lib/proxy_api/monitoring_test.rb +3 -1
- data/test/test_plugin_helper.rb +2 -0
- data/test/unit/host_status/monitoring_status_test.rb +6 -4
- data/test/unit/host_test.rb +2 -0
- data/test/unit/monitoring_result_test.rb +2 -0
- data/test/unit/monitoring_test.rb +2 -0
- metadata +59 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e703d5ad965ed3aecba3fee0dc31a7a2c80a84eab893392484555fda8ba8ab1
|
4
|
+
data.tar.gz: 6dce2771bea3df536cb244aadfbad6483387d71157c4b70d5cbe0256b27f508c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3c24e7c223b0103333d21717636f338176cb2756028d60943c8e6276ffaa366de039dec2b5afd527b5f50464737194b6cc6d5e357f9696d6b56aff167b7fc6e
|
7
|
+
data.tar.gz: ca91aa5af43494a254fbe03bd13cb4e4e30dccfdab8e47befb8252f97b2cce1bd8ab850739993d1675d194f3253a8b5825b248f6d95cc75b6b7c4915252356eb
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Api
|
4
|
+
module V2
|
5
|
+
class DowntimeController < V2::BaseController
|
6
|
+
include Api::Version2
|
7
|
+
include ::ForemanMonitoring::FindHostByClientCert
|
8
|
+
|
9
|
+
authorize_host_by_client_cert %i[create]
|
10
|
+
before_action :find_host, :only => [:create]
|
11
|
+
|
12
|
+
api :POST, '/downtime', N_('Schedule host downtime')
|
13
|
+
param :duration, :number, :desc => N_('Downtime duration (seconds)'), :required => false
|
14
|
+
param :reason, String, :desc => N_('Downtime reason'), :required => false
|
15
|
+
|
16
|
+
def create
|
17
|
+
begin
|
18
|
+
options = {
|
19
|
+
:comment => downtime_params[:reason] || _('Host requested downtime')
|
20
|
+
}
|
21
|
+
if downtime_params.key? :duration
|
22
|
+
options[:start_time] = Time.now.to_i
|
23
|
+
options[:end_time] = Time.now.to_i + downtime_params[:duration].to_i
|
24
|
+
end
|
25
|
+
@host.downtime_host(options)
|
26
|
+
rescue StandardError => e
|
27
|
+
Foreman::Logging.exception('Failed to request downtime', e)
|
28
|
+
render :json => { 'message' => e.message }, :status => :unprocessable_entity
|
29
|
+
return
|
30
|
+
end
|
31
|
+
|
32
|
+
render :json => { 'message' => 'OK' }
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def downtime_params
|
38
|
+
params.permit(:duration, :reason)
|
39
|
+
end
|
40
|
+
|
41
|
+
def find_host
|
42
|
+
@host = detected_host
|
43
|
+
|
44
|
+
return true if @host
|
45
|
+
|
46
|
+
logger.info 'Denying access because no host could be detected.'
|
47
|
+
if User.current
|
48
|
+
render_error 'access_denied',
|
49
|
+
:status => :forbidden,
|
50
|
+
:locals => {
|
51
|
+
:details => 'You need to authenticate with a valid client cert. The DN has to match a known host.'
|
52
|
+
}
|
53
|
+
else
|
54
|
+
render_error 'unauthorized',
|
55
|
+
:status => :unauthorized,
|
56
|
+
:locals => {
|
57
|
+
:user_login => get_client_cert_hostname
|
58
|
+
}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ForemanMonitoring
|
4
|
+
module FindHostByClientCert
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def authorize_host_by_client_cert(actions, _options = {})
|
9
|
+
skip_before_action :require_login, :only => actions, :raise => false
|
10
|
+
skip_before_action :authorize, :only => actions
|
11
|
+
skip_before_action :verify_authenticity_token, :only => actions
|
12
|
+
skip_before_action :set_taxonomy, :only => actions, :raise => false
|
13
|
+
skip_before_action :session_expiry, :update_activity_time, :only => actions
|
14
|
+
before_action(:only => actions) { require_client_cert_or_login }
|
15
|
+
attr_reader :detected_host
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# Permits Hosts authorized by their client cert
|
22
|
+
# or a user with permission
|
23
|
+
def require_client_cert_or_login
|
24
|
+
@detected_host = find_host_by_client_cert
|
25
|
+
|
26
|
+
if detected_host
|
27
|
+
set_admin_user
|
28
|
+
return true
|
29
|
+
end
|
30
|
+
|
31
|
+
require_login
|
32
|
+
unless User.current
|
33
|
+
render_error 'unauthorized', :status => :unauthorized unless performed? && api_request?
|
34
|
+
return false
|
35
|
+
end
|
36
|
+
authorize
|
37
|
+
end
|
38
|
+
|
39
|
+
def find_host_by_client_cert
|
40
|
+
hostname = get_client_cert_hostname
|
41
|
+
|
42
|
+
return unless hostname
|
43
|
+
|
44
|
+
host ||= Host::Base.find_by(certname: hostname) ||
|
45
|
+
Host::Base.find_by(name: hostname)
|
46
|
+
logger.info { "Found Host #{host} by client cert #{hostname}" } if host
|
47
|
+
host
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_client_cert_hostname
|
51
|
+
client_certificate = Foreman::ClientCertificate.new(request: request)
|
52
|
+
return unless client_certificate.verified?
|
53
|
+
|
54
|
+
hostname = client_certificate.subject
|
55
|
+
logger.debug "Extracted hostname '#{hostname}' from client certificate." if hostname
|
56
|
+
hostname
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ForemanMonitoring
|
2
4
|
module HostsControllerExtensions
|
3
5
|
def self.prepended(base)
|
@@ -38,14 +40,14 @@ module ForemanMonitoring
|
|
38
40
|
failed_hosts[host.name] = error_message
|
39
41
|
logger.error "Failed to set a host downtime for #{host}: #{error_message}"
|
40
42
|
end
|
41
|
-
rescue StandardError =>
|
42
|
-
failed_hosts[host.name] =
|
43
|
-
Foreman::Logging.exception(_('Failed to set a host downtime for %s.') % host,
|
43
|
+
rescue StandardError => e
|
44
|
+
failed_hosts[host.name] = e
|
45
|
+
Foreman::Logging.exception(_('Failed to set a host downtime for %s.') % host, e)
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
47
49
|
if failed_hosts.empty?
|
48
|
-
|
50
|
+
success _('A downtime was set for the selected hosts.')
|
49
51
|
else
|
50
52
|
error n_('A downtime clould not be set for host: %s.',
|
51
53
|
'A downtime could not be set for hosts: %s.',
|
@@ -128,7 +130,7 @@ module ForemanMonitoring
|
|
128
130
|
def action_permission
|
129
131
|
case params[:action]
|
130
132
|
when 'downtime', 'select_multiple_downtime', 'update_multiple_downtime'
|
131
|
-
:
|
133
|
+
:manage_downtime
|
132
134
|
when 'select_multiple_monitoring_proxy', 'update_multiple_monitoring_proxy'
|
133
135
|
:edit
|
134
136
|
else
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ForemanMonitoring
|
2
4
|
module HostsHelperExt
|
3
5
|
def multiple_actions
|
@@ -12,14 +14,14 @@ module ForemanMonitoring
|
|
12
14
|
button_group(
|
13
15
|
display_link_if_authorized(_('Downtime'),
|
14
16
|
hash_for_host_path(:id => host).merge(:auth_object => host,
|
15
|
-
:permission => :
|
17
|
+
:permission => :manage_downtime_hosts,
|
16
18
|
:anchor => 'set_host_downtime'),
|
17
19
|
:class => 'btn btn-default',
|
18
20
|
:disabled => !host.monitored?,
|
19
|
-
:title
|
20
|
-
:id
|
21
|
-
:data
|
22
|
-
|
21
|
+
:title => _('Set a downtime for this host'),
|
22
|
+
:id => 'host-downtime',
|
23
|
+
:data => { :toggle => 'modal',
|
24
|
+
:target => '#set_host_downtime' })
|
23
25
|
)
|
24
26
|
)
|
25
27
|
super
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ProxyAPI
|
2
4
|
class Monitoring < ProxyAPI::Resource
|
3
5
|
def initialize(args)
|
@@ -31,6 +33,7 @@ module ProxyAPI
|
|
31
33
|
|
32
34
|
def delete_host(host)
|
33
35
|
raise Foreman::Exception, 'Missing hostname.' if host.blank?
|
36
|
+
|
34
37
|
parse(delete("host/#{host}"))
|
35
38
|
rescue RestClient::ResourceNotFound
|
36
39
|
true
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ForemanMonitoring
|
2
4
|
module HostExtensions
|
3
5
|
def self.prepended(base)
|
@@ -28,6 +30,7 @@ module ForemanMonitoring
|
|
28
30
|
|
29
31
|
def downtime_host(options)
|
30
32
|
return unless monitored?
|
33
|
+
|
31
34
|
begin
|
32
35
|
monitoring.set_downtime_host(self, options)
|
33
36
|
rescue ProxyAPI::ProxyException => e
|
@@ -59,7 +62,7 @@ module ForemanMonitoring
|
|
59
62
|
:architecture => architecture.try(:name),
|
60
63
|
:os => operatingsystem.try(:to_label),
|
61
64
|
:osfamily => operatingsystem.try(:family),
|
62
|
-
:virtual => provider != 'BareMetal',
|
65
|
+
:virtual => virtual.presence || provider != 'BareMetal',
|
63
66
|
:provider => provider,
|
64
67
|
:compute_resource => compute_resource.try(:to_label),
|
65
68
|
:hostgroup => hostgroup.try(:to_label),
|
@@ -1,14 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ForemanMonitoring
|
2
4
|
module HostgroupExtensions
|
3
5
|
extend ActiveSupport::Concern
|
4
6
|
|
5
7
|
def monitoring_proxy
|
6
8
|
return super if ancestry.blank?
|
9
|
+
|
7
10
|
SmartProxy.find_by(id: inherited_monitoring_proxy_id)
|
8
11
|
end
|
9
12
|
|
10
13
|
def inherited_monitoring_proxy_id
|
11
14
|
return monitoring_proxy_id if ancestry.blank?
|
15
|
+
|
12
16
|
self[:monitoring_proxy_id] || self.class.sort_by_ancestry(ancestors.where('monitoring_proxy_id is not NULL')).last.try(:monitoring_proxy_id)
|
13
17
|
end
|
14
18
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Orchestration::Monitoring
|
2
4
|
extend ActiveSupport::Concern
|
3
5
|
|
@@ -10,32 +12,38 @@ module Orchestration::Monitoring
|
|
10
12
|
|
11
13
|
def queue_monitoring
|
12
14
|
return unless monitored? && errors.empty?
|
15
|
+
|
13
16
|
clear_monitoring_object
|
14
17
|
!monitoring_object.key?(:attrs) ? queue_monitoring_create : queue_monitoring_update
|
15
18
|
end
|
16
19
|
|
17
20
|
def queue_monitoring_create
|
18
21
|
return true unless ::Monitoring.create_action?(:create)
|
19
|
-
|
22
|
+
|
23
|
+
queue.create(:name => _('Create monitoring object for %s') % self, :priority => 20,
|
20
24
|
:action => [self, :setMonitoring])
|
21
25
|
end
|
22
26
|
|
23
27
|
def queue_monitoring_update
|
24
28
|
return unless monitoring_update_required?(monitoring_object[:attrs], monitoring_attributes)
|
29
|
+
|
25
30
|
Rails.logger.debug('Detected a change to the monitoring object is required.')
|
26
31
|
return unless ::Monitoring.create_action?(:create)
|
27
|
-
|
32
|
+
|
33
|
+
queue.create(:name => _('Monitoring update for %s') % old, :priority => 2,
|
28
34
|
:action => [self, :setMonitoringUpdate])
|
29
35
|
end
|
30
36
|
|
31
37
|
def queue_monitoring_destroy
|
32
38
|
return unless monitored? && errors.empty?
|
39
|
+
|
33
40
|
if ::Monitoring.delete_action?(:delete)
|
34
|
-
queue.create(:name
|
41
|
+
queue.create(:name => _('Removing monitoring object for %s') % self, :priority => 2,
|
35
42
|
:action => [self, :delMonitoring])
|
36
43
|
end
|
37
44
|
return unless ::Monitoring.delete_action?(:downtime)
|
38
|
-
|
45
|
+
|
46
|
+
queue.create(:name => _('Set monitoring downtime for %s') % self, :priority => 2,
|
39
47
|
:action => [self, :setMonitoringDowntime])
|
40
48
|
end
|
41
49
|
|
@@ -95,6 +103,7 @@ module Orchestration::Monitoring
|
|
95
103
|
|
96
104
|
def monitoring_update_required?(actual_attrs, desired_attrs)
|
97
105
|
return true if actual_attrs.deep_symbolize_keys.keys != desired_attrs.deep_symbolize_keys.keys
|
106
|
+
|
98
107
|
actual_attrs.deep_symbolize_keys.merge(desired_attrs.deep_symbolize_keys) do |k, actual_v, desired_v|
|
99
108
|
if actual_v.is_a?(Hash) && desired_v.is_a?(Hash)
|
100
109
|
return true if monitoring_update_required?(actual_v, desired_v)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module HostStatus
|
2
4
|
class MonitoringStatus < HostStatus::Status
|
3
5
|
OK = 0
|
@@ -14,6 +16,7 @@ module HostStatus
|
|
14
16
|
grouped_results.each_key do |resultset|
|
15
17
|
result, downtime, acknowledged = resultset
|
16
18
|
next if downtime
|
19
|
+
|
17
20
|
result = map_result_to_status(result)
|
18
21
|
result = WARNING if acknowledged || result == UNKNOWN
|
19
22
|
state = result if result > state
|
@@ -23,6 +26,7 @@ module HostStatus
|
|
23
26
|
|
24
27
|
def to_global(_options = {})
|
25
28
|
return HostStatus::Global::OK unless should_affect_global_status?
|
29
|
+
|
26
30
|
case status
|
27
31
|
when OK
|
28
32
|
HostStatus::Global::OK
|
@@ -74,6 +78,7 @@ module HostStatus
|
|
74
78
|
|
75
79
|
def map_result_to_status(result)
|
76
80
|
return result if Rails::VERSION::MAJOR < 5
|
81
|
+
|
77
82
|
case result.to_sym
|
78
83
|
when :ok
|
79
84
|
OK
|
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class MonitoringResult < ApplicationRecord
|
2
|
-
enum :result =>
|
4
|
+
enum :result => { :ok => 0, :warning => 1, :critical => 2, :unknown => 3 }
|
3
5
|
|
4
6
|
belongs_to_host
|
5
7
|
|
@@ -30,11 +32,11 @@ class MonitoringResult < ApplicationRecord
|
|
30
32
|
created = MonitoringResult.where(:host => host, :service => result[:service]).first_or_create
|
31
33
|
# rubocop:disable Rails/Date
|
32
34
|
if created.timestamp.blank? || updates[:timestamp].blank? || (created.timestamp.to_time - updates[:timestamp].to_time) < 2
|
33
|
-
created.
|
35
|
+
created.update(updates)
|
34
36
|
|
35
37
|
if created.persisted?
|
36
38
|
logger.info("Imported monitoring result for #{host} in #{(Time.now.utc - start_time).round(2)} seconds")
|
37
|
-
host.
|
39
|
+
host.get_status(::HostStatus::MonitoringStatus).refresh!
|
38
40
|
end
|
39
41
|
else
|
40
42
|
logger.debug "Skipping monitoring result import for #{host} as it is older than what we have."
|
@@ -46,6 +48,7 @@ class MonitoringResult < ApplicationRecord
|
|
46
48
|
def status
|
47
49
|
return :ok if downtime
|
48
50
|
return :warning if acknowledged
|
51
|
+
|
49
52
|
result.to_sym
|
50
53
|
end
|
51
54
|
|
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Deface::Override.new(:virtual_path => 'hosts/show',
|
4
|
+
:name => 'add_monitoring_result_tab',
|
3
5
|
:insert_bottom => 'ul.nav-tabs',
|
4
|
-
:partial
|
6
|
+
:partial => 'monitoring_results/host_tab')
|
5
7
|
|
6
|
-
Deface::Override.new(:virtual_path
|
7
|
-
:name
|
8
|
+
Deface::Override.new(:virtual_path => 'hosts/show',
|
9
|
+
:name => 'add_monitoring_result_tab_pane',
|
8
10
|
:insert_bottom => 'div.tab-content',
|
9
|
-
:partial
|
11
|
+
:partial => 'monitoring_results/host_tab_pane')
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
2
|
-
|
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',
|
3
5
|
:insert_before => "erb[silent]:contains('end')",
|
4
|
-
:partial
|
6
|
+
:partial => 'hosts/host_downtime_checkbox')
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Deface::Override.new(:virtual_path => 'hosts/show',
|
4
|
+
:name => 'add_monitoring_set_downtime_modal',
|
3
5
|
:insert_after => 'div#review_before_build',
|
4
6
|
:partial => 'hosts/set_host_downtime')
|
data/app/services/monitoring.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Monitoring
|
2
4
|
CREATE_ACTIONS = {
|
3
5
|
'none' => _('None'),
|
@@ -49,6 +51,7 @@ class Monitoring
|
|
49
51
|
def query_host(host)
|
50
52
|
result = proxy_api.query_host(host.name)
|
51
53
|
return {} unless result
|
54
|
+
|
52
55
|
{
|
53
56
|
:attrs => result
|
54
57
|
}
|
data/config/routes.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
Rails.application.routes.draw do
|
2
4
|
namespace :api, :defaults => { :format => 'json' } do
|
3
5
|
scope '(:apiv)', :module => :v2,
|
@@ -5,6 +7,7 @@ Rails.application.routes.draw do
|
|
5
7
|
:apiv => /v1|v2/,
|
6
8
|
:constraints => ApiConstraints.new(:version => 2) do
|
7
9
|
resources :monitoring_results, :only => [:create]
|
10
|
+
resources :downtime, :only => [:create]
|
8
11
|
end
|
9
12
|
end
|
10
13
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class RenameDowntimeHostPermission < ActiveRecord::Migration[5.2]
|
4
|
+
def up
|
5
|
+
# rubocop:disable Rails/SkipsModelValidations
|
6
|
+
Permission.where(name: 'manage_host_downtimes').update_all(name: 'manage_downtime_hosts')
|
7
|
+
# rubocop:enable Rails/SkipsModelValidations
|
8
|
+
end
|
9
|
+
|
10
|
+
def down
|
11
|
+
# rubocop:disable Rails/SkipsModelValidations
|
12
|
+
Permission.where(name: 'manage_downtime_hosts').update_all(name: 'manage_host_downtimes')
|
13
|
+
# rubocop:enable Rails/SkipsModelValidations
|
14
|
+
end
|
15
|
+
end
|
data/lib/foreman_monitoring.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'deface'
|
2
4
|
|
3
5
|
module ForemanMonitoring
|
@@ -18,18 +20,17 @@ module ForemanMonitoring
|
|
18
20
|
|
19
21
|
initializer 'foreman_monitoring.load_default_settings',
|
20
22
|
:before => :load_config_initializers do |_app|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
23
|
+
setting_table_exists = begin
|
24
|
+
Setting.table_exists?
|
25
|
+
rescue StandardError
|
26
|
+
false
|
27
|
+
end
|
28
|
+
require_dependency File.expand_path('../../app/models/setting/monitoring.rb', __dir__) if setting_table_exists
|
28
29
|
end
|
29
30
|
|
30
31
|
initializer 'foreman_monitoring.register_plugin', :before => :finisher_hook do |_app|
|
31
32
|
Foreman::Plugin.register :foreman_monitoring do
|
32
|
-
requires_foreman '>=
|
33
|
+
requires_foreman '>= 2.0'
|
33
34
|
|
34
35
|
apipie_documented_controllers ["#{ForemanMonitoring::Engine.root}/app/controllers/api/v2/*.rb"]
|
35
36
|
|
@@ -37,22 +38,25 @@ module ForemanMonitoring
|
|
37
38
|
permission :view_monitoring_results,
|
38
39
|
{},
|
39
40
|
:resource_type => 'Host'
|
40
|
-
permission :
|
41
|
-
{ :hosts => [:downtime, :select_multiple_downtime, :update_multiple_downtime] },
|
41
|
+
permission :manage_downtime_hosts,
|
42
|
+
{ :hosts => [:downtime, :select_multiple_downtime, :update_multiple_downtime], :'api/v2/downtime' => [:create] },
|
42
43
|
:resource_type => 'Host'
|
43
44
|
permission :upload_monitoring_results,
|
44
45
|
:'api/v2/monitoring_results' => [:create]
|
45
|
-
permission :edit_hosts,
|
46
|
-
{ :hosts => [:select_multiple_monitoring_proxy, :update_multiple_monitoring_proxy] },
|
47
|
-
:resource_type => 'Host'
|
48
46
|
end
|
49
47
|
|
50
|
-
|
51
|
-
|
48
|
+
# Extend built in permissions
|
49
|
+
Foreman::AccessControl.permission(:edit_hosts).actions.concat [
|
50
|
+
'hosts/select_multiple_monitoring_proxy',
|
51
|
+
'hosts/update_multiple_monitoring_proxy'
|
52
|
+
]
|
53
|
+
|
54
|
+
role 'Monitoring viewer', [:view_monitoring_results], 'Role granting permissions to view monitor results'
|
55
|
+
role 'Monitoring manager', [:view_monitoring_results, :manage_downtime_hosts], 'Role granting permissions to view monitor results and manage downtimes'
|
52
56
|
|
53
57
|
register_custom_status HostStatus::MonitoringStatus
|
54
58
|
|
55
|
-
add_controller_action_scope(HostsController, :index) { |base_scope| base_scope.includes(:monitoring_results) }
|
59
|
+
add_controller_action_scope('HostsController', :index) { |base_scope| base_scope.includes(:monitoring_results) }
|
56
60
|
|
57
61
|
monitoring_proxy_options = {
|
58
62
|
:feature => 'Monitoring',
|
@@ -65,23 +69,23 @@ module ForemanMonitoring
|
|
65
69
|
smart_proxy_for Host::Managed, :monitoring_proxy, monitoring_proxy_options
|
66
70
|
smart_proxy_for Hostgroup, :monitoring_proxy, monitoring_proxy_options
|
67
71
|
|
68
|
-
add_controller_action_scope(HostsController, :index) { |base_scope| base_scope.includes(:monitoring_proxy) }
|
72
|
+
add_controller_action_scope('HostsController', :index) { |base_scope| base_scope.includes(:monitoring_proxy) }
|
69
73
|
end
|
70
74
|
end
|
71
75
|
|
72
76
|
config.to_prepare do
|
73
77
|
begin
|
74
|
-
::Host::Managed.
|
75
|
-
::Hostgroup.
|
76
|
-
::HostsHelper.
|
77
|
-
::HostsController.
|
78
|
+
::Host::Managed.prepend(ForemanMonitoring::HostExtensions)
|
79
|
+
::Hostgroup.include(ForemanMonitoring::HostgroupExtensions)
|
80
|
+
::HostsHelper.prepend(ForemanMonitoring::HostsHelperExt)
|
81
|
+
::HostsController.prepend(ForemanMonitoring::HostsControllerExtensions)
|
78
82
|
rescue StandardError => e
|
79
83
|
Rails.logger.warn "ForemanMonitoring: skipping engine hook (#{e})"
|
80
84
|
end
|
81
85
|
end
|
82
86
|
|
83
87
|
initializer 'foreman_monitoring.register_gettext', after: :load_config_initializers do |_app|
|
84
|
-
locale_dir = File.join(File.expand_path('
|
88
|
+
locale_dir = File.join(File.expand_path('../..', __dir__), 'locale')
|
85
89
|
locale_domain = 'foreman_monitoring'
|
86
90
|
Foreman::Gettext::Support.add_text_domain locale_domain, locale_dir
|
87
91
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Tests
|
2
4
|
namespace :test do
|
3
5
|
desc 'Test ForemanMonitoring'
|
@@ -11,7 +13,7 @@ namespace :test do
|
|
11
13
|
end
|
12
14
|
|
13
15
|
namespace :foreman_monitoring do
|
14
|
-
task :
|
16
|
+
task rubocop: :environment do
|
15
17
|
begin
|
16
18
|
require 'rubocop/rake_task'
|
17
19
|
RuboCop::RakeTask.new(:rubocop_foreman_monitoring) do |task|
|
data/locale/gemspec.rb
CHANGED
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_plugin_helper'
|
4
|
+
|
5
|
+
class Api::V2::DowntimeControllerTest < ActionController::TestCase
|
6
|
+
let(:host1) { as_admin { FactoryBot.create(:host, :managed) } }
|
7
|
+
|
8
|
+
context 'with user authentication' do
|
9
|
+
context '#create' do
|
10
|
+
test 'should deny access' do
|
11
|
+
put :create
|
12
|
+
assert_response :forbidden
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'with client cert' do
|
18
|
+
setup do
|
19
|
+
User.current = nil
|
20
|
+
reset_api_credentials
|
21
|
+
|
22
|
+
Setting[:ssl_client_dn_env] = 'SSL_CLIENT_S_DN'
|
23
|
+
Setting[:ssl_client_verify_env] = 'SSL_CLIENT_VERIFY'
|
24
|
+
|
25
|
+
@request.env['HTTPS'] = 'on'
|
26
|
+
@request.env['SSL_CLIENT_S_DN'] = "CN=#{host1.name},DN=example,DN=com"
|
27
|
+
@request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
|
28
|
+
end
|
29
|
+
|
30
|
+
context '#create' do
|
31
|
+
test 'should create downtime' do
|
32
|
+
put :create
|
33
|
+
assert_response :success
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context '#create with duration' do
|
38
|
+
test 'should create downtime with given duration' do
|
39
|
+
Host::Managed.any_instance.expects(:downtime_host).with { |params| params[:end_time] - params[:start_time] == 3600 }
|
40
|
+
put :create, params: { duration: 3600 }
|
41
|
+
assert_response :success
|
42
|
+
end
|
43
|
+
|
44
|
+
test 'should create downtime with given duration as string' do
|
45
|
+
Host::Managed.any_instance.expects(:downtime_host).with { |params| params[:end_time] - params[:start_time] == 3600 }
|
46
|
+
put :create, params: { duration: '3600' }
|
47
|
+
assert_response :success
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context '#create with reason' do
|
52
|
+
test 'should create downtime with given reason' do
|
53
|
+
Host::Managed.any_instance.expects(:downtime_host).with { |params| params[:comment] == 'In testing' }
|
54
|
+
put :create, params: { reason: 'In testing' }
|
55
|
+
assert_response :success
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'without any credentials' do
|
61
|
+
setup do
|
62
|
+
User.current = nil
|
63
|
+
reset_api_credentials
|
64
|
+
end
|
65
|
+
|
66
|
+
context '#create' do
|
67
|
+
test 'should deny access' do
|
68
|
+
post :create
|
69
|
+
assert_response :unauthorized
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/test/factories/feature.rb
CHANGED
data/test/factories/host.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
FactoryBot.modify do
|
2
4
|
factory :host do
|
3
5
|
trait :with_monitoring do
|
@@ -8,7 +10,7 @@ FactoryBot.modify do
|
|
8
10
|
|
9
11
|
trait :with_monitoring_results do
|
10
12
|
transient do
|
11
|
-
monitoring_result_count 20
|
13
|
+
monitoring_result_count { 20 }
|
12
14
|
end
|
13
15
|
after(:create) do |host, evaluator|
|
14
16
|
evaluator.monitoring_result_count.times do
|
@@ -1,30 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
FactoryBot.define do
|
2
4
|
factory :monitoring_result do
|
3
5
|
sequence(:service) { |n| "Service #{n}" }
|
4
6
|
result { rand(0..3) }
|
5
7
|
|
6
8
|
trait :ok do
|
7
|
-
result 0
|
9
|
+
result { 0 }
|
8
10
|
end
|
9
11
|
|
10
12
|
trait :warning do
|
11
|
-
result 1
|
13
|
+
result { 1 }
|
12
14
|
end
|
13
15
|
|
14
16
|
trait :critical do
|
15
|
-
result 2
|
17
|
+
result { 2 }
|
16
18
|
end
|
17
19
|
|
18
20
|
trait :unknown do
|
19
|
-
result 3
|
21
|
+
result { 3 }
|
20
22
|
end
|
21
23
|
|
22
24
|
trait :downtime do
|
23
|
-
downtime true
|
25
|
+
downtime { true }
|
24
26
|
end
|
25
27
|
|
26
28
|
trait :acknowledged do
|
27
|
-
acknowledged true
|
29
|
+
acknowledged { true }
|
28
30
|
end
|
29
31
|
end
|
30
32
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_plugin_helper'
|
2
4
|
|
3
5
|
class HostsControllerExtensionsTest < ActionController::TestCase
|
@@ -22,17 +24,17 @@ class HostsControllerExtensionsTest < ActionController::TestCase
|
|
22
24
|
params: {
|
23
25
|
:id => @host.name,
|
24
26
|
:downtime => {
|
25
|
-
:comment
|
27
|
+
:comment => 'Maintenance work.',
|
26
28
|
:starttime => Time.current,
|
27
|
-
:endtime
|
29
|
+
:endtime => Time.current.advance(:hours => 2)
|
28
30
|
}
|
29
31
|
},
|
30
32
|
session: set_session_user
|
31
33
|
assert_response :found
|
32
34
|
assert_redirected_to host_path(:id => @host)
|
33
35
|
assert_nil flash[:error]
|
34
|
-
assert_not_nil flash[:
|
35
|
-
assert_equal "Created downtime for #{@host}", flash[:
|
36
|
+
assert_not_nil flash[:success]
|
37
|
+
assert_equal "Created downtime for #{@host}", flash[:success]
|
36
38
|
end
|
37
39
|
|
38
40
|
test 'with missing comment param the flash should inform it' do
|
@@ -58,9 +60,9 @@ class HostsControllerExtensionsTest < ActionController::TestCase
|
|
58
60
|
params: {
|
59
61
|
:id => @host.name,
|
60
62
|
:downtime => {
|
61
|
-
:comment
|
63
|
+
:comment => 'Maintenance work.',
|
62
64
|
:starttime => 'invalid',
|
63
|
-
:endtime
|
65
|
+
:endtime => 'invalid'
|
64
66
|
}
|
65
67
|
},
|
66
68
|
session: set_session_user
|
@@ -78,9 +80,9 @@ class HostsControllerExtensionsTest < ActionController::TestCase
|
|
78
80
|
params: {
|
79
81
|
:id => @host.name,
|
80
82
|
:downtime => {
|
81
|
-
:comment
|
83
|
+
:comment => 'Maintenance work.',
|
82
84
|
:starttime => '2017-04-20T10:15',
|
83
|
-
:endtime
|
85
|
+
:endtime => '2017-04-20T12:15'
|
84
86
|
}
|
85
87
|
},
|
86
88
|
session: set_session_user
|
@@ -120,8 +122,8 @@ class HostsControllerExtensionsTest < ActionController::TestCase
|
|
120
122
|
assert_response :found
|
121
123
|
assert_redirected_to hosts_path
|
122
124
|
assert_nil flash[:error]
|
123
|
-
assert_not_nil flash[:
|
124
|
-
assert_equal 'A downtime was set for the selected hosts.', flash[:
|
125
|
+
assert_not_nil flash[:success]
|
126
|
+
assert_equal 'A downtime was set for the selected hosts.', flash[:success]
|
125
127
|
end
|
126
128
|
end
|
127
129
|
|
@@ -151,8 +153,8 @@ class HostsControllerExtensionsTest < ActionController::TestCase
|
|
151
153
|
assert_response :found
|
152
154
|
assert_redirected_to hosts_path
|
153
155
|
assert_nil flash[:error]
|
154
|
-
assert_not_nil flash[:
|
155
|
-
assert_equal 'The power state of the selected hosts will be set to poweroff', flash[:
|
156
|
+
assert_not_nil flash[:success]
|
157
|
+
assert_equal 'The power state of the selected hosts will be set to poweroff', flash[:success]
|
156
158
|
end
|
157
159
|
|
158
160
|
test 'should not set a downtime if not selected' do
|
@@ -170,8 +172,8 @@ class HostsControllerExtensionsTest < ActionController::TestCase
|
|
170
172
|
assert_response :found
|
171
173
|
assert_redirected_to hosts_path
|
172
174
|
assert_nil flash[:error]
|
173
|
-
assert_not_nil flash[:
|
174
|
-
assert_equal 'The power state of the selected hosts will be set to poweroff', flash[:
|
175
|
+
assert_not_nil flash[:success]
|
176
|
+
assert_equal 'The power state of the selected hosts will be set to poweroff', flash[:success]
|
175
177
|
end
|
176
178
|
end
|
177
179
|
|
@@ -196,7 +198,7 @@ class HostsControllerExtensionsTest < ActionController::TestCase
|
|
196
198
|
|
197
199
|
test 'should change the proxy' do
|
198
200
|
hosts.each do |host|
|
199
|
-
|
201
|
+
assert_not_equal monitoring_proxy, host.monitoring_proxy
|
200
202
|
end
|
201
203
|
|
202
204
|
params = {
|
@@ -209,7 +211,7 @@ class HostsControllerExtensionsTest < ActionController::TestCase
|
|
209
211
|
assert_response :found
|
210
212
|
assert_redirected_to hosts_path
|
211
213
|
assert_nil flash[:error]
|
212
|
-
assert_equal "The Monitoring proxy of the selected hosts was set to #{monitoring_proxy.name}", flash[:
|
214
|
+
assert_equal "The Monitoring proxy of the selected hosts was set to #{monitoring_proxy.name}", flash[:success]
|
213
215
|
|
214
216
|
hosts.each do |host|
|
215
217
|
as_admin do
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
|
-
class
|
5
|
+
class ProxyApiMonitoringTest < ActiveSupport::TestCase
|
4
6
|
def setup
|
5
7
|
@url = 'http://localhost:8443'
|
6
8
|
@monitoring = ProxyAPI::Monitoring.new(:url => @url)
|
data/test/test_plugin_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_plugin_helper'
|
2
4
|
|
3
5
|
class MonitoringStatusTest < ActiveSupport::TestCase
|
@@ -61,7 +63,7 @@ class MonitoringStatusTest < ActiveSupport::TestCase
|
|
61
63
|
assert status.relevant?
|
62
64
|
|
63
65
|
host.build = true
|
64
|
-
|
66
|
+
assert_not status.relevant?
|
65
67
|
end
|
66
68
|
|
67
69
|
test '#host_known_in_monitoring? should be true' do
|
@@ -76,10 +78,10 @@ class MonitoringStatusTest < ActiveSupport::TestCase
|
|
76
78
|
context 'status with host without monitoring results' do
|
77
79
|
test '#relevant? is always false when build changes' do
|
78
80
|
host.build = false
|
79
|
-
|
81
|
+
assert_not status.relevant?
|
80
82
|
|
81
83
|
host.build = true
|
82
|
-
|
84
|
+
assert_not status.relevant?
|
83
85
|
end
|
84
86
|
|
85
87
|
test '#refresh! refreshes the date and persists the record' do
|
@@ -90,7 +92,7 @@ class MonitoringStatusTest < ActiveSupport::TestCase
|
|
90
92
|
end
|
91
93
|
|
92
94
|
test '#host_known_in_monitoring? should be false' do
|
93
|
-
|
95
|
+
assert_not status.host_known_in_monitoring?
|
94
96
|
end
|
95
97
|
end
|
96
98
|
end
|
data/test/unit/host_test.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_monitoring
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Timo Goebel
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rdoc
|
@@ -28,16 +28,58 @@ dependencies:
|
|
28
28
|
name: rubocop
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.80.0
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.80.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop-minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop-performance
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
41
83
|
- !ruby/object:Gem::Dependency
|
42
84
|
name: deface
|
43
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -62,7 +104,9 @@ files:
|
|
62
104
|
- LICENSE
|
63
105
|
- README.md
|
64
106
|
- Rakefile
|
107
|
+
- app/controllers/api/v2/downtime_controller.rb
|
65
108
|
- app/controllers/api/v2/monitoring_results_controller.rb
|
109
|
+
- app/controllers/concerns/foreman_monitoring/find_host_by_client_cert.rb
|
66
110
|
- app/controllers/concerns/foreman_monitoring/hosts_controller_extensions.rb
|
67
111
|
- app/helpers/concerns/foreman_monitoring/hosts_helper_ext.rb
|
68
112
|
- app/lib/proxy_api/monitoring.rb
|
@@ -86,6 +130,7 @@ files:
|
|
86
130
|
- config/routes.rb
|
87
131
|
- db/migrate/20160817135723_create_monitoring_results.rb
|
88
132
|
- db/migrate/20161220201510_add_monitoring_proxy_id_to_host_and_hostgroup.rb
|
133
|
+
- db/migrate/201910180900_rename_downtime_host_permission.rb
|
89
134
|
- db/seeds.d/60-monitoring_proxy_feature.rb
|
90
135
|
- lib/foreman_monitoring.rb
|
91
136
|
- lib/foreman_monitoring/engine.rb
|
@@ -95,6 +140,7 @@ files:
|
|
95
140
|
- locale/en/foreman_monitoring.po
|
96
141
|
- locale/foreman_monitoring.pot
|
97
142
|
- locale/gemspec.rb
|
143
|
+
- test/controllers/api/v2/downtime_controller_test.rb
|
98
144
|
- test/factories/feature.rb
|
99
145
|
- test/factories/host.rb
|
100
146
|
- test/factories/monitoring_results.rb
|
@@ -106,11 +152,11 @@ files:
|
|
106
152
|
- test/unit/host_test.rb
|
107
153
|
- test/unit/monitoring_result_test.rb
|
108
154
|
- test/unit/monitoring_test.rb
|
109
|
-
homepage:
|
155
|
+
homepage: https://github.com/theforeman/foreman_monitoring
|
110
156
|
licenses:
|
111
|
-
-
|
157
|
+
- GPL-3.0
|
112
158
|
metadata: {}
|
113
|
-
post_install_message:
|
159
|
+
post_install_message:
|
114
160
|
rdoc_options: []
|
115
161
|
require_paths:
|
116
162
|
- lib
|
@@ -125,9 +171,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
171
|
- !ruby/object:Gem::Version
|
126
172
|
version: '0'
|
127
173
|
requirements: []
|
128
|
-
|
129
|
-
|
130
|
-
signing_key:
|
174
|
+
rubygems_version: 3.1.2
|
175
|
+
signing_key:
|
131
176
|
specification_version: 4
|
132
177
|
summary: Foreman plugin for monitoring system integration.
|
133
178
|
test_files:
|
@@ -141,4 +186,5 @@ test_files:
|
|
141
186
|
- test/factories/host.rb
|
142
187
|
- test/lib/proxy_api/monitoring_test.rb
|
143
188
|
- test/test_plugin_helper.rb
|
189
|
+
- test/controllers/api/v2/downtime_controller_test.rb
|
144
190
|
- test/functional/hosts_controller_test.rb
|