foreman_expire_hosts 6.0.0 → 7.0.2
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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +78 -0
- data/.rubocop.yml +18 -13
- data/.rubocop_todo.yml +11 -31
- data/Gemfile +2 -0
- data/README.md +1 -0
- data/app/controllers/concerns/foreman_expire_hosts/api/v2/hosts_controller_extensions.rb +2 -0
- data/app/controllers/concerns/foreman_expire_hosts/host_controller_extensions.rb +20 -15
- data/app/helpers/concerns/foreman_expire_hosts/audits_helper_extensions.rb +4 -0
- data/app/helpers/concerns/foreman_expire_hosts/hosts_helper_extensions.rb +5 -22
- data/app/helpers/expire_hosts_mailer_helper.rb +3 -0
- data/app/helpers/foreman_expire_hosts/hosts_helper.rb +16 -0
- data/app/mailers/expire_hosts_mailer.rb +3 -0
- data/app/models/concerns/foreman_expire_hosts/host_ext.rb +9 -1
- data/app/models/host_status/expiration_status.rb +3 -0
- data/app/models/setting/expire_hosts.rb +2 -0
- data/app/overrides/add_expired_on_field_to_host_form.rb +4 -2
- data/app/overrides/add_expired_on_field_to_host_show.rb +5 -3
- data/app/overrides/deleted_expired_host_comment_in_audits.rb +8 -6
- data/app/services/foreman_expire_hosts/action/base.rb +9 -2
- data/app/services/foreman_expire_hosts/action/delete_expired_hosts.rb +3 -0
- data/app/services/foreman_expire_hosts/action/stop_expired_hosts.rb +6 -2
- data/app/services/foreman_expire_hosts/expiry_edit_authorizer.rb +2 -0
- data/app/services/foreman_expire_hosts/notification/base.rb +12 -3
- data/app/services/foreman_expire_hosts/notification/deleted_hosts.rb +2 -0
- data/app/services/foreman_expire_hosts/notification/expiry_warning.rb +2 -0
- data/app/services/foreman_expire_hosts/notification/failed_deleted_hosts.rb +2 -0
- data/app/services/foreman_expire_hosts/notification/failed_stopped_hosts.rb +2 -0
- data/app/services/foreman_expire_hosts/notification/stopped_hosts.rb +2 -0
- data/app/services/foreman_expire_hosts/safe_destroy.rb +7 -5
- data/app/services/foreman_expire_hosts/ui_notifications/hosts/base.rb +4 -1
- data/app/services/foreman_expire_hosts/ui_notifications/hosts/expiry_warning.rb +2 -0
- data/app/services/foreman_expire_hosts/ui_notifications/hosts/stopped_host.rb +2 -0
- data/app/views/api/v2/hosts/expiration.json.rabl +2 -0
- data/app/views/hosts/_expired_on_field.html.erb +11 -20
- data/app/views/hosts/select_multiple_expiration.html.erb +10 -15
- data/config/routes.rb +2 -0
- data/db/migrate/20150427101516_add_expiry_on_to_hosts.rb +2 -0
- data/db/seeds.d/80_expire_hosts_ui_notification.rb +2 -0
- data/extra/foreman_expire_hosts.cron +8 -0
- data/foreman_expire_hosts.gemspec +10 -3
- data/lib/expire_hosts_notifications.rb +3 -0
- data/lib/foreman_expire_hosts.rb +2 -0
- data/lib/foreman_expire_hosts/engine.rb +22 -10
- data/lib/foreman_expire_hosts/version.rb +3 -1
- data/lib/tasks/expired_hosts.rake +3 -1
- data/test/factories/foreman_expire_hosts_factories.rb +7 -5
- data/test/functional/api/v2/hosts_controller_test.rb +3 -1
- data/test/functional/concerns/hosts_controller_extensions_test.rb +3 -1
- data/test/helpers/hosts_helper_test.rb +5 -0
- data/test/lib/expire_hosts_notifications_test.rb +91 -45
- data/test/test_plugin_helper.rb +2 -0
- data/test/unit/concerns/host_extensions_test.rb +21 -19
- data/test/unit/expire_hosts_mailer_test.rb +6 -0
- data/test/unit/expiry_edit_authorizer_test.rb +2 -0
- data/test/unit/host_status/expiration_status_test.rb +3 -1
- data/test/unit/safe_destroy_test.rb +3 -1
- metadata +53 -26
- data/app/assets/javascripts/foreman_expire_hosts/application.js +0 -3
- data/app/assets/javascripts/foreman_expire_hosts/datepicker_for_host_expired_on_field.js +0 -27
- data/app/assets/stylesheets/foreman_expire_hosts/application.scss +0 -4
- data/app/overrides/add_js_to_host_index.rb +0 -6
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module HostStatus
|
2
4
|
class ExpirationStatus < HostStatus::Status
|
3
5
|
OK = 0
|
@@ -15,6 +17,7 @@ module HostStatus
|
|
15
17
|
return EXPIRED if host.expired_past_grace_period?
|
16
18
|
return IN_GRACE_PERIOD if host.expired?
|
17
19
|
return PENDING if host.pending_expiration?
|
20
|
+
|
18
21
|
OK
|
19
22
|
end
|
20
23
|
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
Deface::Override.new(
|
2
4
|
:virtual_path => 'hosts/_form',
|
3
|
-
:name
|
5
|
+
:name => 'host_form_expired_on_field',
|
4
6
|
:insert_after => 'div#model_name',
|
5
|
-
:partial
|
7
|
+
:partial => 'hosts/expired_on_field'
|
6
8
|
)
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
Deface::Override.new(
|
2
|
-
:virtual_path
|
3
|
-
:name
|
4
|
+
:virtual_path => 'hosts/show',
|
5
|
+
:name => 'host_expiry_waring_in_show',
|
4
6
|
:insert_before => '#host-show',
|
5
|
-
:partial
|
7
|
+
:partial => 'hosts/expired_message.html.erb'
|
6
8
|
)
|
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
Deface::Override.new(
|
2
|
-
:virtual_path
|
3
|
-
:name
|
4
|
+
:virtual_path => 'audits/_list',
|
5
|
+
:name => 'deleted_expired_host_audit_comment_in_list',
|
4
6
|
:insert_bottom => 'div.row div.audit-content',
|
5
|
-
:text
|
7
|
+
:text => "\n <%= destroyed_expired_host_audit_comment_in_list(audit) %>"
|
6
8
|
)
|
7
9
|
|
8
10
|
Deface::Override.new(
|
9
|
-
:virtual_path
|
10
|
-
:name
|
11
|
+
:virtual_path => 'audits/show',
|
12
|
+
:name => 'deleted_expired_host_audit_comment_in_show',
|
11
13
|
:insert_bottom => 'div#tab1 table',
|
12
|
-
:text
|
14
|
+
:text => "\n <%= destroyed_expired_host_audit_comment_in_show(@audit) %>"
|
13
15
|
)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ForemanExpireHosts
|
2
4
|
module Action
|
3
5
|
class Base
|
@@ -17,9 +19,14 @@ module ForemanExpireHosts
|
|
17
19
|
|
18
20
|
def process
|
19
21
|
hosts.each do |host|
|
20
|
-
|
22
|
+
result = action(host)
|
23
|
+
next if result.nil?
|
24
|
+
|
25
|
+
if result
|
26
|
+
logger.info "Action #{self.class.name} for host #{host.name} was successful."
|
21
27
|
self.successful_hosts << host
|
22
28
|
else
|
29
|
+
logger.info "Action #{self.class.name} for host #{host.name} failed."
|
23
30
|
self.failed_hosts << host
|
24
31
|
end
|
25
32
|
end
|
@@ -51,7 +58,7 @@ module ForemanExpireHosts
|
|
51
58
|
}
|
52
59
|
end
|
53
60
|
|
54
|
-
delegate :logger, :to => :
|
61
|
+
delegate :logger, :to => :ForemanExpireHosts
|
55
62
|
end
|
56
63
|
end
|
57
64
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ForemanExpireHosts
|
2
4
|
module Action
|
3
5
|
class DeleteExpiredHosts < Base
|
@@ -8,6 +10,7 @@ module ForemanExpireHosts
|
|
8
10
|
end
|
9
11
|
|
10
12
|
def action(host)
|
13
|
+
logger.info "Destroying expired host #{host}."
|
11
14
|
SafeDestroy.new(host).destroy!
|
12
15
|
end
|
13
16
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ForemanExpireHosts
|
2
4
|
module Action
|
3
5
|
class StopExpiredHosts < Base
|
@@ -8,8 +10,10 @@ module ForemanExpireHosts
|
|
8
10
|
end
|
9
11
|
|
10
12
|
def action(host)
|
11
|
-
return
|
12
|
-
|
13
|
+
return false unless host.supports_power?
|
14
|
+
return unless host.power.ready?
|
15
|
+
|
16
|
+
logger.info "Powering down expired host in grace period #{host}."
|
13
17
|
host.power.stop
|
14
18
|
rescue StandardError
|
15
19
|
false
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ForemanExpireHosts
|
2
4
|
module Notification
|
3
5
|
class Base
|
@@ -24,22 +26,27 @@ module ForemanExpireHosts
|
|
24
26
|
end
|
25
27
|
|
26
28
|
def deliver_mail_notification(recipient, hosts)
|
29
|
+
return true if hosts.empty?
|
30
|
+
|
31
|
+
logger.info "Deliving mail notification '#{humanized_name}' for hosts #{hosts.to_sentence} to #{recipient}."
|
32
|
+
|
27
33
|
build_mail_notification(recipient, hosts).deliver_now
|
28
|
-
rescue SocketError, Net::SMTPError =>
|
34
|
+
rescue SocketError, Net::SMTPError => e
|
29
35
|
message = _('Failed to deliver %{notification_name} for Hosts %{hosts}') % {
|
30
36
|
:notification_name => humanized_name,
|
31
37
|
:hosts => hosts.map(&:name).to_sentence
|
32
38
|
}
|
33
|
-
Foreman::Logging.exception(message,
|
39
|
+
Foreman::Logging.exception(message, e)
|
34
40
|
end
|
35
41
|
|
36
42
|
def deliver_ui_notifications
|
37
43
|
all_hosts.each do |host|
|
44
|
+
logger.info "Deliving UI notification '#{humanized_name}' for host '#{host}'."
|
38
45
|
build_ui_notification(host).deliver!
|
39
46
|
end
|
40
47
|
end
|
41
48
|
|
42
|
-
delegate :logger, :to => :
|
49
|
+
delegate :logger, :to => :ForemanExpireHosts
|
43
50
|
|
44
51
|
def humanized_name
|
45
52
|
_('Notification')
|
@@ -59,11 +66,13 @@ module ForemanExpireHosts
|
|
59
66
|
return global_recipients if global_recipients.present?
|
60
67
|
return [User.anonymous_admin] if host.owner.blank?
|
61
68
|
return [host.owner] if host.owner_type == 'User'
|
69
|
+
|
62
70
|
host.owner.all_users
|
63
71
|
end
|
64
72
|
|
65
73
|
def additional_recipients
|
66
74
|
return [] if Setting[:host_expiry_email_recipients].nil?
|
75
|
+
|
67
76
|
Setting[:host_expiry_email_recipients].split(',').compact.map(&:strip)
|
68
77
|
end
|
69
78
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ForemanExpireHosts
|
2
4
|
class SafeDestroy
|
3
5
|
# See http://projects.theforeman.org/issues/14702 for reasoning.
|
@@ -13,18 +15,18 @@ module ForemanExpireHosts
|
|
13
15
|
# See https://community.theforeman.org/t/how-to-properly-destroy-a-content-host/8621
|
14
16
|
# for reasoning.
|
15
17
|
if subject.is_a?(Host::Base) && with_katello?
|
16
|
-
Katello::RegistrationManager.unregister_host(
|
18
|
+
Katello::RegistrationManager.unregister_host(subject)
|
17
19
|
else
|
18
20
|
subject.destroy!
|
19
21
|
end
|
20
|
-
rescue ActiveRecord::RecordNotDestroyed =>
|
22
|
+
rescue ActiveRecord::RecordNotDestroyed => e
|
21
23
|
message = _('Failed to delete %{class_name} %{subject}: %{message} - Errors: %{errors}') % {
|
22
24
|
:class_name => subject.class.name,
|
23
25
|
:subject => subject,
|
24
|
-
:message =>
|
25
|
-
:errors =>
|
26
|
+
:message => e.message,
|
27
|
+
:errors => e.record.errors.full_messages.to_sentence
|
26
28
|
}
|
27
|
-
Foreman::Logging.exception(message,
|
29
|
+
Foreman::Logging.exception(message, e)
|
28
30
|
false
|
29
31
|
end
|
30
32
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ForemanExpireHosts
|
2
4
|
module UINotifications
|
3
5
|
module Hosts
|
@@ -6,6 +8,7 @@ module ForemanExpireHosts
|
|
6
8
|
|
7
9
|
def create
|
8
10
|
return add_notification unless find_notification
|
11
|
+
|
9
12
|
redeliver! if redeliver?
|
10
13
|
find_notification
|
11
14
|
end
|
@@ -45,7 +48,7 @@ module ForemanExpireHosts
|
|
45
48
|
|
46
49
|
def redeliver!
|
47
50
|
recipients = find_notification.notification_recipients
|
48
|
-
recipients.update_all(seen: false)
|
51
|
+
recipients.update_all(seen: false)
|
49
52
|
recipients.pluck(:user_id).each do |user_id|
|
50
53
|
::UINotifications::CacheHandler.new(user_id).clear
|
51
54
|
end
|
@@ -1,22 +1,13 @@
|
|
1
|
-
<% if @host.can_modify_expiry_date? %>
|
2
|
-
<%= stylesheet 'foreman_expire_hosts/application' %>
|
3
|
-
<%= javascript 'foreman_expire_hosts/application' %>
|
4
|
-
<% end %>
|
5
1
|
<%= datepicker_f f, :expired_on,
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
:help_block => ('<span class="pficon-warning-triangle-o"></span> '.html_safe + _('You are not allowed to change the expiry date of this host.') unless @host.can_modify_expiry_date?),
|
18
|
-
:readonly => !@host.can_modify_expiry_date?,
|
19
|
-
:help_inline => popover('Auto Expiry', _('Host will be deleted automatically on given expiry date.') + '<br>'.html_safe +
|
20
|
-
_('Leave blank to keep the host until deleted manually')),
|
21
|
-
:onfocus => 'append_shortcuts()'
|
2
|
+
{
|
3
|
+
:label => _('Expires on'),
|
4
|
+
:autocomplete => false,
|
5
|
+
:include_blank => true,
|
6
|
+
:use_month_numbers => false,
|
7
|
+
:start_year => Date.today.year,
|
8
|
+
:help_block => ('<span class="pficon-warning-triangle-o"></span> '.html_safe + _('You are not allowed to change the expiry date of this host.') unless @host.can_modify_expiry_date?),
|
9
|
+
:disabled => !@host.can_modify_expiry_date?,
|
10
|
+
:help_inline => popover('Auto Expiry', _('Expired hosts will be deleted automatically after the grace period has passed.') + '<br>'.html_safe +
|
11
|
+
_('If you do not want this host to expire and do not want it to be deleted automatically, do not specify an expiry date.'))
|
12
|
+
}
|
22
13
|
%>
|
@@ -1,23 +1,18 @@
|
|
1
|
-
<%= stylesheet 'foreman_expire_hosts/application' %>
|
2
|
-
<%= javascript 'foreman_expire_hosts/application' %>
|
3
1
|
<%= render 'selected_hosts', :hosts => @hosts %>
|
4
2
|
|
5
3
|
<%= form_for :host, :url => update_multiple_expiration_hosts_path(:host_ids => params[:host_ids]) do |f| %>
|
6
4
|
|
7
|
-
<%= _('
|
5
|
+
<%= _('Hosts will be deleted automatically on the given expiry date. Leave blank to clear expiration date.') %>
|
8
6
|
|
9
7
|
<%= datepicker_f f, :expired_on,
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
:autocomplete => false,
|
20
|
-
:placeholder => 'dd/mm/yyyy',
|
21
|
-
:onfocus => 'append_shortcuts()'
|
8
|
+
{
|
9
|
+
:autocomplete => false,
|
10
|
+
:include_blank => true,
|
11
|
+
:use_month_numbers => false,
|
12
|
+
:start_year => Date.today.year
|
13
|
+
},
|
14
|
+
{
|
15
|
+
:onchange => 'tfm.hosts.table.toggleMultipleOkButton(this);'
|
16
|
+
}
|
22
17
|
%>
|
23
18
|
<% end %>
|
data/config/routes.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
Foreman::Application.routes.draw do
|
2
4
|
post 'expired_hosts/select_multiple_expiration' => 'hosts#select_multiple_expiration', as: 'select_multiple_expiration_hosts'
|
3
5
|
post 'expired_hosts/update_multiple_expiration' => 'hosts#update_multiple_expiration', as: 'update_multiple_expiration_hosts'
|
@@ -0,0 +1,8 @@
|
|
1
|
+
SHELL=/bin/sh
|
2
|
+
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
3
|
+
|
4
|
+
RAILS_ENV=production
|
5
|
+
FOREMAN_HOME=/usr/share/foreman
|
6
|
+
|
7
|
+
# Send out notifications about expired hosts
|
8
|
+
45 7 * * * foreman /usr/sbin/foreman-rake expired_hosts:deliver_notifications >>/var/log/foreman/expired_hosts.log 2>&1
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require File.expand_path('lib/foreman_expire_hosts/version', __dir__)
|
2
4
|
require 'date'
|
3
5
|
|
@@ -8,7 +10,10 @@ Gem::Specification.new do |s|
|
|
8
10
|
s.authors = ['Nagarjuna Rachaneni', 'Timo Goebel']
|
9
11
|
s.email = ['nn.nagarjuna@gmail.com', 'mail@timogoebel.name']
|
10
12
|
s.summary = 'Foreman plugin for limiting host lifetime'
|
11
|
-
s.description =
|
13
|
+
s.description = <<~DESC
|
14
|
+
A Foreman plugin that allows hosts to expire at a configurable date.
|
15
|
+
Hosts will be shut down and automatically deleted after a grace period.
|
16
|
+
DESC
|
12
17
|
s.homepage = 'https://github.com/theforeman/foreman_expire_hosts'
|
13
18
|
s.licenses = ['GPL-3.0']
|
14
19
|
|
@@ -18,9 +23,11 @@ Gem::Specification.new do |s|
|
|
18
23
|
|
19
24
|
s.require_paths = ['lib']
|
20
25
|
|
21
|
-
s.add_dependency 'bootstrap-datepicker-rails'
|
22
26
|
s.add_dependency 'deface'
|
23
27
|
|
24
28
|
s.add_development_dependency 'rdoc'
|
25
|
-
s.add_development_dependency 'rubocop', '0.
|
29
|
+
s.add_development_dependency 'rubocop', '~> 0.80.0'
|
30
|
+
s.add_development_dependency 'rubocop-minitest', '~> 0.7.0'
|
31
|
+
s.add_development_dependency 'rubocop-performance', '~> 1.5.2'
|
32
|
+
s.add_development_dependency 'rubocop-rails', '~> 2.4.2'
|
26
33
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ExpireHostsNotifications
|
2
4
|
class << self
|
3
5
|
def delete_expired_hosts
|
@@ -10,6 +12,7 @@ module ExpireHostsNotifications
|
|
10
12
|
|
11
13
|
def deliver_expiry_warning_notification(num = 1) # notify1_days_before_expiry
|
12
14
|
return unless [1, 2].include?(num)
|
15
|
+
|
13
16
|
days_before_expiry = Setting["notify#{num}_days_before_host_expiry"].to_i
|
14
17
|
expiry_date = (Date.today + days_before_expiry)
|
15
18
|
notifiable_hosts = Host.with_expire_date(expiry_date).preload(:owner)
|