foreman_monitoring 0.1.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -7
  3. data/Rakefile +0 -0
  4. data/app/controllers/api/v2/downtime_controller.rb +63 -0
  5. data/app/controllers/api/v2/monitoring_results_controller.rb +5 -4
  6. data/app/controllers/concerns/foreman_monitoring/find_host_by_client_cert.rb +60 -0
  7. data/app/controllers/concerns/foreman_monitoring/hosts_controller_extensions.rb +21 -20
  8. data/app/helpers/concerns/foreman_monitoring/hosts_helper_ext.rb +16 -19
  9. data/app/lib/proxy_api/monitoring.rb +9 -6
  10. data/app/models/concerns/foreman_monitoring/host_extensions.rb +15 -14
  11. data/app/models/concerns/foreman_monitoring/hostgroup_extensions.rb +7 -3
  12. data/app/models/concerns/orchestration/monitoring.rb +22 -15
  13. data/app/models/host_status/monitoring_status.rb +7 -4
  14. data/app/models/monitoring_result.rb +13 -6
  15. data/app/models/setting/monitoring.rb +4 -2
  16. data/app/overrides/add_host_monitoring_result_tab.rb +8 -6
  17. data/app/overrides/add_host_multiple_power_set_downtime_checkbox.rb +5 -3
  18. data/app/overrides/add_host_set_downtime_modal.rb +4 -2
  19. data/app/services/monitoring.rb +3 -0
  20. data/app/views/hosts/_downtime_fields.html.erb +2 -2
  21. data/app/views/monitoring_results/_host_tab_pane.html.erb +2 -2
  22. data/config/routes.rb +3 -0
  23. data/db/migrate/20160817135723_create_monitoring_results.rb +5 -1
  24. data/db/migrate/20161220201510_add_monitoring_proxy_id_to_host_and_hostgroup.rb +3 -1
  25. data/db/migrate/201910180900_rename_downtime_host_permission.rb +15 -0
  26. data/db/seeds.d/60-monitoring_proxy_feature.rb +2 -0
  27. data/lib/foreman_monitoring.rb +2 -0
  28. data/lib/foreman_monitoring/engine.rb +32 -28
  29. data/lib/foreman_monitoring/version.rb +3 -1
  30. data/lib/tasks/foreman_monitoring_tasks.rake +5 -5
  31. data/locale/gemspec.rb +2 -0
  32. data/test/controllers/api/v2/downtime_controller_test.rb +73 -0
  33. data/test/factories/feature.rb +4 -2
  34. data/test/factories/host.rb +6 -4
  35. data/test/factories/monitoring_results.rb +9 -7
  36. data/test/factories/smart_proxy.rb +3 -1
  37. data/test/functional/hosts_controller_test.rb +65 -52
  38. data/test/lib/proxy_api/monitoring_test.rb +16 -14
  39. data/test/test_plugin_helper.rb +5 -3
  40. data/test/unit/host_status/monitoring_status_test.rb +18 -16
  41. data/test/unit/host_test.rb +6 -4
  42. data/test/unit/monitoring_result_test.rb +75 -0
  43. data/test/unit/monitoring_test.rb +5 -3
  44. metadata +62 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f742aa658a66234e28555d6dbba4beca116e6ba3d49db3c02898bd7cc295a5d9
4
- data.tar.gz: f11b41bb8dc37e78431df10c3fc255f7680039293e7e0c9ff0268a4c975d49ef
3
+ metadata.gz: 6bc195afe4c0af30313894eaf37dcf99c36625fe510998783df94932111c9891
4
+ data.tar.gz: 8d37c47d99c8d48163242ce490159c59a6a4e6c2588709daac0bac841a450c5a
5
5
  SHA512:
6
- metadata.gz: f7dbdfc58ea1b7669eefff4b603ccc4f813b87a3aadbb4cd4a48ad86de3899403b440709d1b2a1f9145dc5b4b4487875ad0a33de031142d70e47d139278043d1
7
- data.tar.gz: 39f27d2331c23bd24392d1abcaa47dc4ec9757463a27503518d501581ba2b276acc2528fa58b2e76f632f58ac00cb91801060d09a821a9853e0754ced75342dc
6
+ metadata.gz: cf715511ef2835a64702b2f865c6380c178dd8c70b2038428ea3a0c9a72fefcef4715ec4c2bcca82fbf687c9ea5a463c5e041009fe7e795cb6aab6484020d6f3
7
+ data.tar.gz: 8c4c4cbaad0dffa2f7d338d19e116cc58c05272b262d36d5bf221137391577a414dcd3ba83c34d78c46207bf8298675529a988d42fd736961751687325b615b1
data/README.md CHANGED
@@ -17,7 +17,7 @@ The gem name is `foreman_monitoring`.
17
17
 
18
18
  RPM users can install the `tfm-rubygem-foreman_monitoring` package.
19
19
 
20
- Deb users can install the `ruby-foreman_monitoring` package.
20
+ Deb users can install the `ruby-foreman-monitoring` package.
21
21
 
22
22
  If using the gem as installation source database enhancement and service restart must
23
23
  be done manually.
@@ -28,6 +28,15 @@ foreman-rake db:seed
28
28
  touch ~foreman/tmp/restart.txt
29
29
  ```
30
30
 
31
+ ## Compatibility
32
+
33
+ | Foreman Version | Plugin Version |
34
+ | --------------- | --------------:|
35
+ | >= 1.15 | ~> 0.1 |
36
+ | >= 1.17 | ~> 1.0 |
37
+ | >= 2.0 | ~> 2.0 |
38
+ | >= 2.2 | ~> 2.1 |
39
+
31
40
  # Usage
32
41
 
33
42
  For managing a host in the monitoring solution a Smart Proxy providing
@@ -35,15 +44,15 @@ the `monitoring` feature has to be assigned. This can be done during
35
44
  provisioning or as a bulk action from the host overview.
36
45
 
37
46
  You can configure the default action which will be done during host
38
- provisioning and deprovisioning. Provisioning allows to create a monitoring
39
- object or take no action while deprovisioing allows to delete the monitoring
40
- object, set a downtime or take no action. For rebuild it will by default
47
+ provisioning and de-provisioning. Provisioning allows to create a monitoring
48
+ object or take no action while de-provisoning allows deleting the monitoring
49
+ object, set a downtime or take no action. For rebuild, it will by default
41
50
  set a downtime.
42
51
 
43
52
  The plugin will show you the monitoring status as a sub-status and a detail
44
53
  panel. You can configure if the sub-status should affect the global status.
45
54
 
46
- Furthermore it allows to individually set a downtime at the host detail view
55
+ Furthermore, it allows to individually set a downtime at the host detail view
47
56
  or as a bulk action from the host overview.
48
57
 
49
58
  # Troubleshooting
@@ -51,8 +60,8 @@ or as a bulk action from the host overview.
51
60
  Logging entries relevant to the plug-in will be located in the Foreman's log
52
61
  which is by default `/var/log/foreman/production.log`.
53
62
 
54
- Also check the troubleshooting section of the Smart Proxy plug-in if problems
55
- occure in the underlying communication.
63
+ Also, check the troubleshooting section of the Smart Proxy plug-in if problems
64
+ occur in the underlying communication.
56
65
 
57
66
  ## Contributing
58
67
 
data/Rakefile CHANGED
File without changes
@@ -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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Api
2
4
  module V2
3
5
  class MonitoringResultsController < V2::BaseController
@@ -17,10 +19,9 @@ module Api
17
19
 
18
20
  def create
19
21
  begin
20
- MonitoringResult.import(monitoring_result_params.with_indifferent_access)
21
- rescue => e
22
- logger.error "Failed to import monitoring result: #{e.message}"
23
- logger.debug e.backtrace.join("\n")
22
+ MonitoringResult.import(monitoring_result_params.to_h.with_indifferent_access)
23
+ rescue StandardError => e
24
+ Foreman::Logging.exception('Failed to import monitoring result', e)
24
25
  render :json => { 'message' => e.message }, :status => :unprocessable_entity
25
26
  return
26
27
  end
@@ -0,0 +1,60 @@
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 :check_user_enabled, :only => actions, :raise => false
11
+ skip_before_action :authorize, :only => actions
12
+ skip_before_action :verify_authenticity_token, :only => actions
13
+ skip_before_action :set_taxonomy, :only => actions, :raise => false
14
+ skip_before_action :session_expiry, :update_activity_time, :only => actions
15
+ before_action(:only => actions) { require_client_cert_or_login }
16
+ attr_reader :detected_host
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ # Permits Hosts authorized by their client cert
23
+ # or a user with permission
24
+ def require_client_cert_or_login
25
+ @detected_host = find_host_by_client_cert
26
+
27
+ if detected_host
28
+ set_admin_user
29
+ return true
30
+ end
31
+
32
+ require_login
33
+ unless User.current
34
+ render_error 'unauthorized', :status => :unauthorized unless performed? && api_request?
35
+ return false
36
+ end
37
+ authorize
38
+ end
39
+
40
+ def find_host_by_client_cert
41
+ hostname = get_client_cert_hostname
42
+
43
+ return unless hostname
44
+
45
+ host ||= Host::Base.find_by(certname: hostname) ||
46
+ Host::Base.find_by(name: hostname)
47
+ logger.info { "Found Host #{host} by client cert #{hostname}" } if host
48
+ host
49
+ end
50
+
51
+ def get_client_cert_hostname
52
+ client_certificate = Foreman::ClientCertificate.new(request: request)
53
+ return unless client_certificate.verified?
54
+
55
+ hostname = client_certificate.subject
56
+ logger.debug "Extracted hostname '#{hostname}' from client certificate." if hostname
57
+ hostname
58
+ end
59
+ end
60
+ end
@@ -1,18 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ForemanMonitoring
2
4
  module HostsControllerExtensions
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- before_action :find_resource_with_monitoring, :only => [:downtime]
7
- before_action :find_multiple_with_monitoring, :only => %i[select_multiple_downtime update_multiple_downtime
8
- select_multiple_monitoring_proxy update_multiple_monitoring_proxy]
9
- before_action :validate_host_downtime_params, :only => [:downtime]
10
- before_action :validate_hosts_downtime_params, :only => [:update_multiple_downtime]
11
- before_action :validate_multiple_monitoring_proxy, :only => :update_multiple_monitoring_proxy
12
-
13
- alias_method :find_resource_with_monitoring, :find_resource
14
- alias_method :find_multiple_with_monitoring, :find_multiple
15
- alias_method_chain :update_multiple_power_state, :monitoring
5
+ def self.prepended(base)
6
+ base.class_eval do
7
+ before_action :find_resource_with_monitoring, :only => [:downtime]
8
+ before_action :find_multiple_with_monitoring, :only => %i[select_multiple_downtime update_multiple_downtime
9
+ select_multiple_monitoring_proxy update_multiple_monitoring_proxy]
10
+ before_action :validate_host_downtime_params, :only => [:downtime]
11
+ before_action :validate_hosts_downtime_params, :only => [:update_multiple_downtime]
12
+ before_action :validate_multiple_monitoring_proxy, :only => :update_multiple_monitoring_proxy
13
+
14
+ alias_method :find_resource_with_monitoring, :find_resource
15
+ alias_method :find_multiple_with_monitoring, :find_multiple
16
+ end
16
17
  end
17
18
 
18
19
  def downtime
@@ -39,14 +40,14 @@ module ForemanMonitoring
39
40
  failed_hosts[host.name] = error_message
40
41
  logger.error "Failed to set a host downtime for #{host}: #{error_message}"
41
42
  end
42
- rescue => error
43
- failed_hosts[host.name] = error
44
- Foreman::Logging.exception(_('Failed to set a host downtime for %s.') % host, error)
43
+ rescue StandardError => e
44
+ failed_hosts[host.name] = e
45
+ Foreman::Logging.exception(_('Failed to set a host downtime for %s.') % host, e)
45
46
  end
46
47
  end
47
48
 
48
49
  if failed_hosts.empty?
49
- notice _('A downtime was set for the selected hosts.')
50
+ success _('A downtime was set for the selected hosts.')
50
51
  else
51
52
  error n_('A downtime clould not be set for host: %s.',
52
53
  'A downtime could not be set for hosts: %s.',
@@ -65,7 +66,7 @@ module ForemanMonitoring
65
66
  update_multiple_proxy(_('Monitoring'), :monitoring_proxy=)
66
67
  end
67
68
 
68
- def update_multiple_power_state_with_monitoring
69
+ def update_multiple_power_state
69
70
  options = {
70
71
  :comment => 'Power state changed in Foreman',
71
72
  :author => "Foreman User #{User.current}",
@@ -86,7 +87,7 @@ module ForemanMonitoring
86
87
  end
87
88
  end
88
89
  end
89
- update_multiple_power_state_without_monitoring
90
+ super
90
91
  end
91
92
 
92
93
  private
@@ -129,7 +130,7 @@ module ForemanMonitoring
129
130
  def action_permission
130
131
  case params[:action]
131
132
  when 'downtime', 'select_multiple_downtime', 'update_multiple_downtime'
132
- :downtime
133
+ :manage_downtime
133
134
  when 'select_multiple_monitoring_proxy', 'update_multiple_monitoring_proxy'
134
135
  :edit
135
136
  else
@@ -1,33 +1,30 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ForemanMonitoring
2
4
  module HostsHelperExt
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- alias_method_chain :host_title_actions, :monitoring
7
- alias_method_chain :multiple_actions, :monitoring
8
- end
9
-
10
- def multiple_actions_with_monitoring
11
- return multiple_actions_without_monitoring unless authorized_for(:controller => :hosts, :action => :select_multiple_downtime)
12
- multiple_actions_without_monitoring + [[_('Set downtime'), select_multiple_downtime_hosts_path], [_('Change Monitoring Proxy'), select_multiple_monitoring_proxy_hosts_path]]
5
+ def multiple_actions
6
+ actions = super
7
+ actions << [_('Set downtime'), select_multiple_downtime_hosts_path] if authorized_for(:controller => :hosts, :action => :select_multiple_downtime)
8
+ actions << [_('Change Monitoring Proxy'), select_multiple_monitoring_proxy_hosts_path] if authorized_for(:controller => :hosts, :action => :select_multiple_monitoring_proxy)
9
+ actions
13
10
  end
14
11
 
15
- def host_title_actions_with_monitoring(host)
12
+ def host_title_actions(host)
16
13
  title_actions(
17
14
  button_group(
18
15
  display_link_if_authorized(_('Downtime'),
19
16
  hash_for_host_path(:id => host).merge(:auth_object => host,
20
- :permission => :manage_host_downtimes,
17
+ :permission => :manage_downtime_hosts,
21
18
  :anchor => 'set_host_downtime'),
22
19
  :class => 'btn btn-default',
23
20
  :disabled => !host.monitored?,
24
- :title => _('Set a downtime for this host'),
25
- :id => 'host-downtime',
26
- :data => { :toggle => 'modal',
27
- :target => '#set_host_downtime' })
21
+ :title => _('Set a downtime for this host'),
22
+ :id => 'host-downtime',
23
+ :data => { :toggle => 'modal',
24
+ :target => '#set_host_downtime' })
28
25
  )
29
26
  )
30
- host_title_actions_without_monitoring(host)
27
+ super
31
28
  end
32
29
 
33
30
  def host_monitoring_result_icon_class(result)
@@ -58,10 +55,10 @@ module ForemanMonitoring
58
55
  end
59
56
  end
60
57
 
61
- def datetime_f(f, attr, options = {})
58
+ def monitoring_datetime_f(f, attr, options = {})
62
59
  field(f, attr, options) do
63
60
  addClass options, 'form-control'
64
- f.datetime_local_field attr, options
61
+ f.datetime_field attr, options
65
62
  end
66
63
  end
67
64
  end
@@ -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)
@@ -7,34 +9,35 @@ module ProxyAPI
7
9
 
8
10
  def create_host_downtime(host, args = {})
9
11
  parse(post(args, "downtime/host/#{host}"))
10
- rescue => e
12
+ rescue StandardError => e
11
13
  raise ProxyException.new(url, e, N_('Unable to set downtime for %s') % host)
12
14
  end
13
15
 
14
16
  def remove_host_downtime(host, args = {})
15
17
  parse(delete("downtime/host/#{host}?#{args.to_query}"))
16
- rescue => e
18
+ rescue StandardError => e
17
19
  raise ProxyException.new(url, e, N_('Unable to remove downtime for %s') % host)
18
20
  end
19
21
 
20
22
  def create_host(host, attributes = {})
21
23
  parse(put({ :attributes => attributes }, "host/#{host}"))
22
- rescue => e
24
+ rescue StandardError => e
23
25
  raise ProxyException.new(url, e, N_('Unable to create monitoring host object for %s') % host)
24
26
  end
25
27
 
26
28
  def update_host(host, attributes = {})
27
29
  parse(post({ :attributes => attributes }, "host/#{host}"))
28
- rescue => e
30
+ rescue StandardError => e
29
31
  raise ProxyException.new(url, e, N_('Unable to update monitoring host object for %s') % host)
30
32
  end
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
37
- rescue => e
40
+ rescue StandardError => e
38
41
  raise ProxyException.new(url, e, N_('Unable to delete monitoring host object for %s') % host)
39
42
  end
40
43
 
@@ -42,7 +45,7 @@ module ProxyAPI
42
45
  parse(get("host/#{host}"))
43
46
  rescue RestClient::ResourceNotFound
44
47
  nil
45
- rescue => e
48
+ rescue StandardError => e
46
49
  raise ProxyException.new(url, e, N_('Unable to query monitoring host object for %{host}: %{message}') % { :host => host, :message => e.try(:response) || e.try(:message) })
47
50
  end
48
51
  end
@@ -1,15 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ForemanMonitoring
2
4
  module HostExtensions
3
- extend ActiveSupport::Concern
4
- included do
5
- include Orchestration::Monitoring
6
-
7
- after_build :downtime_host_build
5
+ def self.prepended(base)
6
+ base.class_eval do
7
+ include Orchestration::Monitoring
8
8
 
9
- alias_method_chain :smart_proxy_ids, :monitoring_proxy
10
- alias_method_chain :hostgroup_inherited_attributes, :monitoring
9
+ after_build :downtime_host_build
11
10
 
12
- has_many :monitoring_results, :dependent => :destroy, :foreign_key => 'host_id'
11
+ has_many :monitoring_results, :dependent => :destroy, :foreign_key => 'host_id', :inverse_of => :host
12
+ end
13
13
  end
14
14
 
15
15
  def monitoring_status(options = {})
@@ -30,6 +30,7 @@ module ForemanMonitoring
30
30
 
31
31
  def downtime_host(options)
32
32
  return unless monitored?
33
+
33
34
  begin
34
35
  monitoring.set_downtime_host(self, options)
35
36
  rescue ProxyAPI::ProxyException => e
@@ -42,12 +43,12 @@ module ForemanMonitoring
42
43
  monitoring_proxy.present?
43
44
  end
44
45
 
45
- def hostgroup_inherited_attributes_with_monitoring
46
- hostgroup_inherited_attributes_without_monitoring + ['monitoring_proxy_id']
46
+ def hostgroup_inherited_attributes
47
+ super + ['monitoring_proxy_id']
47
48
  end
48
49
 
49
- def smart_proxy_ids_with_monitoring_proxy
50
- ids = smart_proxy_ids_without_monitoring_proxy
50
+ def smart_proxy_ids
51
+ ids = super
51
52
  [monitoring_proxy, hostgroup.try(:monitoring_proxy)].compact.each do |proxy|
52
53
  ids << proxy.id
53
54
  end
@@ -61,12 +62,12 @@ module ForemanMonitoring
61
62
  :architecture => architecture.try(:name),
62
63
  :os => operatingsystem.try(:to_label),
63
64
  :osfamily => operatingsystem.try(:family),
64
- :virtual => provider != 'BareMetal',
65
+ :virtual => virtual.presence || provider != 'BareMetal',
65
66
  :provider => provider,
66
67
  :compute_resource => compute_resource.try(:to_label),
67
68
  :hostgroup => hostgroup.try(:to_label),
68
69
  :organization => organization.try(:name),
69
- :location => organization.try(:name),
70
+ :location => location.try(:name),
70
71
  :comment => comment,
71
72
  :environment => environment.try(:to_s),
72
73
  :owner_name => owner.try(:name)