foreman_expire_hosts 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rubocop.yml +54 -0
- data/.rubocop_todo.yml +74 -0
- data/Gemfile +3 -0
- data/LICENSE +674 -0
- data/README.md +124 -0
- data/app/assets/javascripts/foreman_expire_hosts/application.js +3 -0
- data/app/assets/javascripts/foreman_expire_hosts/datepicker_for_host_expired_on_field.js +27 -0
- data/app/assets/stylesheets/foreman_expire_hosts/application.scss +4 -0
- data/app/controllers/concerns/foreman_expire_hosts/host_controller_extensions.rb +73 -0
- data/app/helpers/concerns/foreman_expire_hosts/hosts_helper_extensions.rb +41 -0
- data/app/helpers/expire_hosts_mailer_helper.rb +15 -0
- data/app/mailers/expire_hosts_mailer.rb +37 -0
- data/app/models/concerns/foreman_expire_hosts/host_ext.rb +86 -0
- data/app/models/host_status/expiration_status.rb +57 -0
- data/app/models/setting/expire_hosts.rb +21 -0
- data/app/overrides/add_expired_on_field_to_host_form.rb +6 -0
- data/app/overrides/add_expired_on_field_to_host_show.rb +6 -0
- data/app/overrides/add_js_to_host_index.rb +6 -0
- data/app/overrides/deleted_expired_host_comment_in_audits.rb +13 -0
- data/app/views/expire_hosts_mailer/_hosts_table.html.erb +40 -0
- data/app/views/expire_hosts_mailer/deleted_hosts_notification.html.erb +3 -0
- data/app/views/expire_hosts_mailer/expiry_warning_notification.html.erb +4 -0
- data/app/views/expire_hosts_mailer/failed_to_delete_hosts_notification.html.erb +4 -0
- data/app/views/expire_hosts_mailer/failed_to_stop_hosts_notification.html.erb +4 -0
- data/app/views/expire_hosts_mailer/stopped_hosts_notification.html.erb +4 -0
- data/app/views/hosts/_expired_message.html.erb +4 -0
- data/app/views/hosts/_expired_on_field.html.erb +20 -0
- data/app/views/hosts/select_multiple_expiration.html.erb +23 -0
- data/config/routes.rb +4 -0
- data/db/migrate/20150427101516_add_expiry_on_to_hosts.rb +5 -0
- data/foreman_expire_hosts.gemspec +26 -0
- data/lib/expire_hosts_notifications.rb +121 -0
- data/lib/foreman_expire_hosts/engine.rb +61 -0
- data/lib/foreman_expire_hosts/version.rb +3 -0
- data/lib/foreman_expire_hosts.rb +3 -0
- data/lib/tasks/expired_hosts.rake +46 -0
- data/test/factories/foreman_expire_hosts_factories.rb +15 -0
- data/test/functional/concerns/hosts_controller_extensions_test.rb +45 -0
- data/test/test_plugin_helper.rb +10 -0
- data/test/unit/concerns/host_extensions_test.rb +136 -0
- data/test/unit/host_status/expiration_status_test.rb +28 -0
- metadata +153 -0
data/README.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# foreman\_expire\_hosts
|
2
|
+
|
3
|
+
# Context
|
4
|
+
|
5
|
+
Foreman makes host creation extremely simple for a sysadmin or a user. However this simplicity lead to wasteful usage of compute resources. foreman_expiry plugin allows to specify an expiry date for the host. On this date the host will be deleted.
|
6
|
+
|
7
|
+
This plugin add expired on(date) field to host form under Additional Information section. If we create any host with expiry date, then that host will be stopped on given date and then deleted. If host has null/blank for expired on field then that host will be live forever (until it deleted manually).
|
8
|
+
|
9
|
+
This plugin will send two warning notification before host expiry (see settings.yaml). It also sends notifications when the host stopped on its expiry date and when host is deleted after few days (configured in settings).
|
10
|
+
|
11
|
+
# Screenshots
|
12
|
+
![Expiry date field in host form](https://raw.githubusercontent.com/ingenico-group/screenshots/master/foreman_host_expiry/expiry-date-field-in-host-form.png)
|
13
|
+
|
14
|
+
![Expiry date field in host show page](https://raw.githubusercontent.com/ingenico-group/screenshots/master/foreman_host_expiry/expiry-date-in-host-show-page.png)
|
15
|
+
|
16
|
+
![Plugin Settings](https://raw.githubusercontent.com/ingenico-group/screenshots/master/foreman_host_expiry/settings.png)
|
17
|
+
|
18
|
+
|
19
|
+
# Installation
|
20
|
+
Please see the Foreman manual for appropriate instructions:
|
21
|
+
|
22
|
+
* [Foreman: How to Install a Plugin](http://theforeman.org/manuals/latest/index.html#6.Plugins)
|
23
|
+
|
24
|
+
Example installation from source.
|
25
|
+
Require foreman_expire_hosts gem installation (edit `~foreman/bundler.d/Gemfile.local.rb`):
|
26
|
+
|
27
|
+
```yaml
|
28
|
+
gem 'foreman_expire_hosts', :git => "https://github.com/ingenico-group/foreman_expire_hosts.git"
|
29
|
+
```
|
30
|
+
|
31
|
+
Update Foreman with the new gems:
|
32
|
+
|
33
|
+
bundle update foreman_expire_hosts
|
34
|
+
|
35
|
+
# Dependency
|
36
|
+
|
37
|
+
This gem required uglifier, execjs and therubyracer gems to load assets. If you install this plugin through RPM package, please install ruby193-rubygem-uglifier, ruby193-rubygem-execjs and ruby193-rubygem-therubyracer rpm package before installing this plugin RPM package
|
38
|
+
|
39
|
+
# Post installation
|
40
|
+
|
41
|
+
This plugin needs additional column in hosts table. Please run migration with below command
|
42
|
+
|
43
|
+
```yaml
|
44
|
+
VERSION=20150427101516 RAILS_ENV=production rake db:migrate:up
|
45
|
+
```
|
46
|
+
|
47
|
+
Add below line to crontab under root user to take appropriate action on expiring/expired hosts and notify user about those hosts. This cronjob will run at 11:30 PM(Midnight)
|
48
|
+
|
49
|
+
|
50
|
+
```
|
51
|
+
30 23 * * * /usr/sbin/foreman-rake expired_hosts:deliver_notifications >> /var/log/foreman/expired_hosts.log 2>&1
|
52
|
+
```
|
53
|
+
|
54
|
+
# Pre remove
|
55
|
+
|
56
|
+
If we want to remove this feature and remove expired_on column from hosts table, please run below rake task and remove this gem from the Gemfile
|
57
|
+
|
58
|
+
```yaml
|
59
|
+
VERSION=20150427101516 RAILS_ENV=production rake db:migrate:down
|
60
|
+
```
|
61
|
+
|
62
|
+
# Configuration
|
63
|
+
|
64
|
+
This plugin will add configurations to settings table and are editable from settings page
|
65
|
+
|
66
|
+
![Plugin Settings](https://raw.githubusercontent.com/ingenico-group/screenshots/master/foreman_host_expiry/settings.png)
|
67
|
+
|
68
|
+
NOTE: After installing this plugin, please update administrator email in Foreman Web UI (More -> Settings -> General) with valid email. This can be used to send notification when plugin failed to deliver notifications to its owner.
|
69
|
+
|
70
|
+
|
71
|
+
# Foreman API to add expiry date to host
|
72
|
+
|
73
|
+
Existing foreman host create/edit API can be used to add/update host's expiry date. For example
|
74
|
+
|
75
|
+
Create host with expiry date
|
76
|
+
|
77
|
+
```yaml
|
78
|
+
POST /api/hosts
|
79
|
+
{
|
80
|
+
"host": {
|
81
|
+
"name": "testhost11",
|
82
|
+
"environment_id": "334344675",
|
83
|
+
"domain_id": "22495316",
|
84
|
+
"ip": "10.0.0.20",
|
85
|
+
"mac": "52:53:00:1e:85:93",
|
86
|
+
"ptable_id": "980190962",
|
87
|
+
"medium_id": "980190962",
|
88
|
+
"architecture_id": "501905019",
|
89
|
+
"operatingsystem_id": "1073012828",
|
90
|
+
"puppet_proxy_id": "980190962",
|
91
|
+
"compute_resource_id": "980190962",
|
92
|
+
"root_pass": "xybxa6JUkz63w",
|
93
|
+
"location_id": "255093256",
|
94
|
+
"organization_id": "447626438",
|
95
|
+
"expired_on": "30/12/2014" # dd/mm/yyyy format
|
96
|
+
}
|
97
|
+
}
|
98
|
+
```
|
99
|
+
|
100
|
+
curl command example
|
101
|
+
|
102
|
+
```yaml
|
103
|
+
curl -u admin:changeme 'https://your-foreman-url.com/api/hosts' -d 'host[name]=testhost11&host[expired_on]=30/12/2014&......' -X POST
|
104
|
+
```
|
105
|
+
Update host expiry date
|
106
|
+
|
107
|
+
```yaml
|
108
|
+
POST /api/hosts/testhost11
|
109
|
+
{
|
110
|
+
"host": {
|
111
|
+
"expired_on": "30/12/2014" # dd/mm/yyyy format
|
112
|
+
}
|
113
|
+
}
|
114
|
+
```
|
115
|
+
|
116
|
+
curl command example
|
117
|
+
|
118
|
+
```yaml
|
119
|
+
curl -u admin:changeme 'https://your-foreman-url.com/api/hosts/testhost11' -d 'host[expired_on]=30/12/2014' -X PUT
|
120
|
+
```
|
121
|
+
|
122
|
+
## License
|
123
|
+
|
124
|
+
GPLv3
|
@@ -0,0 +1,27 @@
|
|
1
|
+
var shortcuts = {"1 day": 1, "1 week": 7, "1 month": 30, "1 year": 365, "3 days": 3, "3 weeks": 21, "3 months": 90};
|
2
|
+
function append_shortcuts() {
|
3
|
+
if ($(".datepicker-days #datepicker_shortcuts").length == 0) {
|
4
|
+
var shortcuts_html = "<div id='datepicker_shortcuts'><div>";
|
5
|
+
var shortcut_item = 1;
|
6
|
+
$.each(shortcuts, function (lable, days) {
|
7
|
+
var today = new Date();
|
8
|
+
today.setDate(today.getDate() + days);
|
9
|
+
if (shortcut_item == 5) {
|
10
|
+
shortcuts_html += "</div><div style='padding-top: 3px'>"
|
11
|
+
}
|
12
|
+
shortcuts_html += "<a style='width: 65px;' class='btn btn-default btn-xs' role='button' title='" + $.fn.datepicker.dates.en.monthsShort[today.getMonth()] + " " + today.getDate() + " " + today.getFullYear() + "' onclick='populate_date_from_days(" + days + ")'>" + lable + "</a> ";
|
13
|
+
shortcut_item += 1
|
14
|
+
});
|
15
|
+
shortcuts_html += "</div></div>";
|
16
|
+
$(".datepicker-days table").before(shortcuts_html)
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
function populate_date_from_days(shortcut_days) {
|
21
|
+
var today = new Date();
|
22
|
+
today.setDate(today.getDate() + shortcut_days);
|
23
|
+
$('#host_expired_on').datepicker('setDate', today);
|
24
|
+
$('#host_expired_on').datepicker('remove');
|
25
|
+
//$('#host_expired_on').val(today.getDate()+'/'+(today.getMonth()+1)+'/'+today.getFullYear())
|
26
|
+
//$('#host_expired_on').datepicker('hide')
|
27
|
+
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module ForemanExpireHosts
|
2
|
+
module HostControllerExtensions
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
before_filter :validate_multiple_expiration, :only => :update_multiple_expiration
|
7
|
+
before_filter :find_multiple, :only => [:select_multiple_expiration, :update_multiple_expiration]
|
8
|
+
alias_method_chain :action_permission, :expire_hosts
|
9
|
+
end
|
10
|
+
|
11
|
+
def select_multiple_expiration
|
12
|
+
end
|
13
|
+
|
14
|
+
def update_multiple_expiration
|
15
|
+
expiration_date = params[:host][:expired_on]
|
16
|
+
expiration_date = Date.parse(expiration_date) if expiration_date.present?
|
17
|
+
|
18
|
+
failed_hosts = {}
|
19
|
+
|
20
|
+
@hosts.each do |host|
|
21
|
+
begin
|
22
|
+
host.expired_on = expiration_date
|
23
|
+
host.save!
|
24
|
+
rescue => error
|
25
|
+
failed_hosts[host.name] = error
|
26
|
+
message = if expiration_date.present?
|
27
|
+
_('Failed to set expiration date for %{host} to %{expiration_date}.') % {:host => host, :expiration_date => l(expiration_date)}
|
28
|
+
else
|
29
|
+
_('Failed to clear expiration date for %s.') % host
|
30
|
+
end
|
31
|
+
Foreman::Logging.exception(message, error)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
if failed_hosts.empty?
|
36
|
+
if expiration_date.present?
|
37
|
+
notice _('The expiration date of the selected hosts was set to %s.') % l(expiration_date)
|
38
|
+
else
|
39
|
+
notice _('The expiration date of the selected hosts was cleared.')
|
40
|
+
end
|
41
|
+
else
|
42
|
+
error n_('The expiration date could not be set for host: %s.',
|
43
|
+
'The expiration date could not be set for hosts: %s.',
|
44
|
+
failed_hosts.count) % failed_hosts.map { |h, err| "#{h} (#{err})" }.to_sentence
|
45
|
+
end
|
46
|
+
redirect_back_or_to hosts_path
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def validate_multiple_expiration
|
52
|
+
if params[:host].nil? || (expiration_date = params[:host][:expired_on]).nil?
|
53
|
+
error _('No expiration date selected!')
|
54
|
+
redirect_to(select_multiple_expiration_hosts_path) && (return false)
|
55
|
+
end
|
56
|
+
begin
|
57
|
+
Date.parse(expiration_date) if expiration_date.present?
|
58
|
+
rescue ArgumentError
|
59
|
+
error _('Invalid expiration date!')
|
60
|
+
redirect_to(select_multiple_expiration_hosts_path) && (return false)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def action_permission_with_expire_hosts
|
65
|
+
case params[:action]
|
66
|
+
when 'select_multiple_expiration', 'update_multiple_expiration'
|
67
|
+
:edit
|
68
|
+
else
|
69
|
+
action_permission_without_expire_hosts
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ForemanExpireHosts
|
2
|
+
module HostsHelperExtensions
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
alias_method_chain :multiple_actions, :expire_hosts
|
7
|
+
end
|
8
|
+
|
9
|
+
def multiple_actions_with_expire_hosts
|
10
|
+
multiple_actions_without_expire_hosts + [[_('Change Expiration'), select_multiple_expiration_hosts_path]]
|
11
|
+
end
|
12
|
+
|
13
|
+
def host_expiry_warning_message(host)
|
14
|
+
return nil unless host.expires?
|
15
|
+
if host.expired_past_grace_period?
|
16
|
+
message = _('This host has expired %s ago and needs to be deleted manually.') % time_ago_in_words(host.expired_on)
|
17
|
+
elsif host.expired?
|
18
|
+
message = _('This host has expired %{time_ago} ago and will be deleted on %{delete_date}.') % {:delete_date => l(host.expiration_grace_period_end_date), :time_ago => time_ago_in_words(host.expired_on)}
|
19
|
+
elsif host.expires_today?
|
20
|
+
message = _('This host will expire today.')
|
21
|
+
elsif host.pending_expiration?
|
22
|
+
message = _('This host will expire in %{distance_of_time} (on %{expire_date}).') % {:expire_date => l(host.expired_on), :distance_of_time => future_time_in_words(host.expired_on)}
|
23
|
+
end
|
24
|
+
message
|
25
|
+
end
|
26
|
+
|
27
|
+
def destroyed_expired_host_audit_comment_in_list(audit)
|
28
|
+
return unless audit.auditable_type.to_s == 'Host' && audit.action == 'destroy' && !audit.comment.blank?
|
29
|
+
"<div style='color: #737373;font-size: 14px'>Comment: #{audit.comment}</div>".html_safe
|
30
|
+
end
|
31
|
+
|
32
|
+
def destroyed_expired_host_audit_comment_in_show(audit)
|
33
|
+
return unless audit.auditable_type.to_s == 'Host' && audit.action == 'destroy' && !audit.comment.blank?
|
34
|
+
"<tr><td>Comment</td><td>#{audit.comment}</td></tr>".html_safe
|
35
|
+
end
|
36
|
+
|
37
|
+
def future_time_in_words(to_time, options = {})
|
38
|
+
distance_of_time_in_words(to_time, Time.current, options)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ExpireHostsMailerHelper
|
2
|
+
def relative_date(date, opts = {})
|
3
|
+
return _('N/A') if date.blank?
|
4
|
+
opts[:tense] ||= :future if Date.today < date
|
5
|
+
opts[:tense] ||= :past if Date.today > date
|
6
|
+
|
7
|
+
if opts[:tense] == :future
|
8
|
+
_('in %s') % (time_ago_in_words date)
|
9
|
+
elsif opts[:tense] == :past
|
10
|
+
_('%s ago') % (time_ago_in_words date)
|
11
|
+
else
|
12
|
+
_('today')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class ExpireHostsMailer < ApplicationMailer
|
2
|
+
|
3
|
+
default :content_type => 'text/html', :from => Setting[:email_reply_address] || 'noreply@your-foreman.com'
|
4
|
+
|
5
|
+
def deleted_hosts_notification(emails, hosts)
|
6
|
+
@hosts = hosts
|
7
|
+
mail(:to => emails, :subject => 'Deleted expired hosts in Foreman', :importance => 'High')
|
8
|
+
end
|
9
|
+
|
10
|
+
def failed_to_delete_hosts_notification(emails, hosts)
|
11
|
+
@hosts = hosts
|
12
|
+
mail(:to => emails, :subject => 'Failed to delete expired hosts in Foreman', :importance => 'High')
|
13
|
+
end
|
14
|
+
|
15
|
+
def stopped_hosts_notification(emails, delete_date, hosts)
|
16
|
+
@hosts = hosts
|
17
|
+
@delete_date = delete_date
|
18
|
+
mail(:to => emails, :subject => 'Stopped expired hosts in Foreman', :importance => 'High') do |format|
|
19
|
+
format.html { render :layout => 'application_mailer' }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def failed_to_stop_hosts_notification(emails, hosts)
|
24
|
+
@hosts = hosts
|
25
|
+
mail(:to => emails, :subject => 'Failed to stop expired hosts in Foreman', :importance => 'High') do |format|
|
26
|
+
format.html { render :layout => 'application_mailer' }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def expiry_warning_notification(emails, expiry_date, hosts)
|
31
|
+
@hosts = hosts
|
32
|
+
@expiry_date = expiry_date
|
33
|
+
mail(:to => emails, :subject => 'Expiring hosts in foreman', :importance => 'High') do |format|
|
34
|
+
format.html { render :layout => 'application_mailer' }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module ForemanExpireHosts
|
2
|
+
module HostExt
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
after_validation :validate_expired_on
|
7
|
+
attr_accessible :expired_on
|
8
|
+
|
9
|
+
validates :expired_on, :presence => true, :if => -> { Setting[:is_host_expiry_date_mandatory] }
|
10
|
+
|
11
|
+
has_one :expiration_status_object, :class_name => 'HostStatus::ExpirationStatus', :foreign_key => 'host_id'
|
12
|
+
|
13
|
+
before_validation :refresh_expiration_status
|
14
|
+
|
15
|
+
scope :expiring, -> { where('expired_on IS NOT NULL') }
|
16
|
+
scope :with_expire_date, ->(date) { expiring.where('expired_on = ?', date) }
|
17
|
+
scope :expired, -> { expiring.where('expired_on < ?', Date.today) }
|
18
|
+
scope :expiring_today, -> { expiring.with_expire_date(Date.today) }
|
19
|
+
scope :expired_past_grace_period, -> { expiring.where('expired_on < ?', Date.today + Setting[:days_to_delete_after_host_expiration].to_i) }
|
20
|
+
|
21
|
+
scoped_search :on => :expired_on, :complete_value => :true, :rename => :expires
|
22
|
+
end
|
23
|
+
|
24
|
+
def validate_expired_on
|
25
|
+
if self.expires?
|
26
|
+
begin
|
27
|
+
unless expired_on.to_s.to_date > Date.today
|
28
|
+
errors.add(:expired_on, _('must be in the future'))
|
29
|
+
end
|
30
|
+
rescue => e
|
31
|
+
errors.add(:expired_on, _('is invalid'))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
if self.changed.include?('expired_on')
|
35
|
+
unless can_modify_expiry_date?
|
36
|
+
errors.add(:expired_on, _('no permission to edit'))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
errors[:expired_on].empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
def expires?
|
43
|
+
expired_on.present?
|
44
|
+
end
|
45
|
+
|
46
|
+
def expires_today?
|
47
|
+
return false unless expires?
|
48
|
+
expired_on.to_date == Date.today
|
49
|
+
end
|
50
|
+
|
51
|
+
def expired?
|
52
|
+
return false unless expires?
|
53
|
+
expired_on.to_date < Date.today
|
54
|
+
end
|
55
|
+
|
56
|
+
def expiration_grace_period_end_date
|
57
|
+
return nil unless expires?
|
58
|
+
expired_on + Setting[:days_to_delete_after_host_expiration].to_i
|
59
|
+
end
|
60
|
+
|
61
|
+
def expired_past_grace_period?
|
62
|
+
return false unless expires?
|
63
|
+
expiration_grace_period_end_date < Date.today
|
64
|
+
end
|
65
|
+
|
66
|
+
def pending_expiration_start_date
|
67
|
+
Date.today - Setting['notify1_days_before_host_expiry'].to_i
|
68
|
+
end
|
69
|
+
|
70
|
+
def pending_expiration?
|
71
|
+
return false unless expires?
|
72
|
+
return false if expired?
|
73
|
+
pending_expiration_start_date <= expired_on
|
74
|
+
end
|
75
|
+
|
76
|
+
def can_modify_expiry_date?
|
77
|
+
(new_record? || (defined?(Rails::Console) || (User.current && (User.current.admin || (Setting[:can_owner_modify_host_expiry_date] || ((owner_type == 'User' && owner.id == User.current.id) || (owner_type == 'Usergroup' && owner.users.map(&:id).include?(User.current.id))))))))
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def refresh_expiration_status
|
83
|
+
self.get_status(HostStatus::ExpirationStatus).refresh
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module HostStatus
|
2
|
+
class ExpirationStatus < HostStatus::Status
|
3
|
+
OK = 0
|
4
|
+
EXPIRED = 1
|
5
|
+
IN_GRACE_PERIOD = 2
|
6
|
+
EXPIRES_TODAY = 3
|
7
|
+
PENDING = 4
|
8
|
+
|
9
|
+
def self.status_name
|
10
|
+
N_('Expiration Status')
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_status(_options = {})
|
14
|
+
return EXPIRED if host.expired_past_grace_period?
|
15
|
+
return IN_GRACE_PERIOD if host.expired?
|
16
|
+
return EXPIRES_TODAY if host.expires_today?
|
17
|
+
return PENDING if host.pending_expiration?
|
18
|
+
OK
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_global(_options = {})
|
22
|
+
case to_status
|
23
|
+
when OK
|
24
|
+
HostStatus::Global::OK
|
25
|
+
when EXPIRES_TODAY
|
26
|
+
HostStatus::Global::WARN
|
27
|
+
when IN_GRACE_PERIOD
|
28
|
+
HostStatus::Global::ERROR
|
29
|
+
when EXPIRED
|
30
|
+
HostStatus::Global::ERROR
|
31
|
+
when PENDING
|
32
|
+
HostStatus::Global::ERROR
|
33
|
+
else
|
34
|
+
HostStatus::Global::OK
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_label(_options = {})
|
39
|
+
case to_status
|
40
|
+
when OK
|
41
|
+
N_('Expires on %s') % I18n.l(host.expired_on)
|
42
|
+
when EXPIRES_TODAY
|
43
|
+
N_('Expires today')
|
44
|
+
when IN_GRACE_PERIOD
|
45
|
+
N_('Expired on %s, in grace period') % I18n.l(host.expired_on)
|
46
|
+
when EXPIRED
|
47
|
+
N_('Expired on %s') % I18n.l(host.expired_on)
|
48
|
+
else
|
49
|
+
N_('Pending expiration on %s') % I18n.l(host.expired_on)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def relevant?(options = {})
|
54
|
+
host.expires?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Setting::ExpireHosts < Setting
|
2
|
+
|
3
|
+
def self.load_defaults
|
4
|
+
# Check the table exists
|
5
|
+
return unless super
|
6
|
+
|
7
|
+
self.transaction do
|
8
|
+
[
|
9
|
+
self.set('is_host_expiry_date_mandatory', N_('Make expiry date field mandatory on host creation/update'), false, N_('Require host expiry date')),
|
10
|
+
self.set('can_owner_modify_host_expiry_date', N_('Allow host owner to modify host expiry date field. If the field is false then admin only can edit expiry field'), false, N_('Host owner can modify host expiry date')),
|
11
|
+
self.set('notify1_days_before_host_expiry', N_('Send first notification to owner of hosts about his hosts expiring in given days. Must be integer only'), 7, N_('First expiry notification')),
|
12
|
+
self.set('notify2_days_before_host_expiry', N_('Send second notification to owner of hosts about his hosts expiring in given days. Must be integer only'), 1, N_('Second expiry notification')),
|
13
|
+
self.set('days_to_delete_after_host_expiration', N_('Delete expired hosts after given days of hosts expiry date. Must be integer only'), 3, N_('Expiry grace period in days')),
|
14
|
+
self.set('host_expiry_email_recipients', N_('All notifications will be delivered to its owner. If any other users/admins need to receive those expiry wanting notifications then those emails can be configured here. This must be string and multiple emails can give with coma(,) separated'), 'foreman-admin@your_foreman.com', N_('Expiry e-mail recipients'))
|
15
|
+
].each { |s| self.create! s.update(:category => 'Setting::ExpireHosts') }
|
16
|
+
end
|
17
|
+
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Deface::Override.new(
|
2
|
+
:virtual_path => 'audits/_list',
|
3
|
+
:name => 'deleted_expired_host_audit_comment_in_list',
|
4
|
+
:insert_bottom => 'div.row div.audit-content',
|
5
|
+
:text => "\n <%= destroyed_expired_host_audit_comment_in_list(audit) %>"
|
6
|
+
)
|
7
|
+
|
8
|
+
Deface::Override.new(
|
9
|
+
:virtual_path => 'audits/show',
|
10
|
+
:name => 'deleted_expired_host_audit_comment_in_show',
|
11
|
+
:insert_bottom => 'div#tab1 table',
|
12
|
+
:text => "\n <%= destroyed_expired_host_audit_comment_in_show(@audit) %>"
|
13
|
+
)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<table>
|
2
|
+
<thead>
|
3
|
+
<tr>
|
4
|
+
<th>
|
5
|
+
<%= _('Hostname') %>
|
6
|
+
</th>
|
7
|
+
<th>
|
8
|
+
<%= _('Host group') %>
|
9
|
+
</th>
|
10
|
+
<th>
|
11
|
+
<%= _('Environment') %>
|
12
|
+
</th>
|
13
|
+
<th>
|
14
|
+
<%= _('Expiration Date') %>
|
15
|
+
</th>
|
16
|
+
</tr>
|
17
|
+
</thead>
|
18
|
+
<tbody>
|
19
|
+
<% hosts.each do |host| %>
|
20
|
+
<tr>
|
21
|
+
<td class="hosts-rows">
|
22
|
+
<% if link_to_hosts %>
|
23
|
+
<%= link_to host, host_url(:id => host, :only_path => true) %>
|
24
|
+
<% else %>
|
25
|
+
<%= host %>
|
26
|
+
<% end %>
|
27
|
+
</td>
|
28
|
+
<td class="hosts-rows">
|
29
|
+
<%= host.hostgroup %>
|
30
|
+
</td>
|
31
|
+
<td class="hosts-rows">
|
32
|
+
<%= host.environment %>
|
33
|
+
</td>
|
34
|
+
<td class="hosts-rows">
|
35
|
+
<%= "#{l(host.expired_on)} (#{relative_date(host.expired_on)})" if host.expires? %>
|
36
|
+
</td>
|
37
|
+
</tr>
|
38
|
+
<% end %>
|
39
|
+
</tbody>
|
40
|
+
</table>
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<%= _('The following hosts have been expired in Foreman and will be stopped for now. These hosts will be destroyed on %s. Please change their expiry date and power them on if you want to keep the hosts.') % l @delete_date %>
|
2
|
+
<br/><br/>
|
3
|
+
|
4
|
+
<%= render 'hosts_table', :hosts => @hosts, :link_to_hosts => true %>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<% if @host.can_modify_expiry_date? %>
|
2
|
+
<%= stylesheet 'foreman_expire_hosts/application' %>
|
3
|
+
<%= javascript 'foreman_expire_hosts/application' %>
|
4
|
+
<% end %>
|
5
|
+
<%= text_f f, :expired_on,
|
6
|
+
:value => @host.expired_on.try(:strftime, '%d/%m/%Y'),
|
7
|
+
:data => { provide: @host.can_modify_expiry_date? ? 'datepicker' : 'readonly',
|
8
|
+
orientation: 'top left',
|
9
|
+
date_autoclose: true,
|
10
|
+
date_clear_btn: true,
|
11
|
+
date_format: 'dd/mm/yyyy',
|
12
|
+
date_start_date: Date.tomorrow.strftime('%d/%m/%Y'),
|
13
|
+
date_today_highlight: true
|
14
|
+
},
|
15
|
+
:autocomplete => false,
|
16
|
+
:placeholder => 'dd/mm/yyyy',
|
17
|
+
:help_inline => popover('Auto Expiry', 'Host will be deleted automatically on given expired date.
|
18
|
+
<br> Leave blank to keep the host until deleted manually'),
|
19
|
+
:onfocus => 'append_shortcuts()'
|
20
|
+
%>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<%= stylesheet 'foreman_expire_hosts/application' %>
|
2
|
+
<%= javascript 'foreman_expire_hosts/application' %>
|
3
|
+
<%= render 'selected_hosts', :hosts => @hosts %>
|
4
|
+
|
5
|
+
<%= form_for :host, :url => update_multiple_expiration_hosts_path(:host_ids => params[:host_ids]) do |f| %>
|
6
|
+
|
7
|
+
<%= _('Host will be deleted automatically on given expired date. Leave blank to clear expiration date.') %>
|
8
|
+
|
9
|
+
<%= text_f f, :expired_on,
|
10
|
+
:value => (Date.today + 14).strftime('%d/%m/%Y'),
|
11
|
+
:data => { provide: 'datepicker',
|
12
|
+
orientation: 'top left',
|
13
|
+
date_autoclose: true,
|
14
|
+
date_clear_btn: true,
|
15
|
+
date_format: 'dd/mm/yyyy',
|
16
|
+
date_start_date: Date.tomorrow.strftime('%d/%m/%Y'),
|
17
|
+
date_today_highlight: true
|
18
|
+
},
|
19
|
+
:autocomplete => false,
|
20
|
+
:placeholder => 'dd/mm/yyyy',
|
21
|
+
:onfocus => 'append_shortcuts()'
|
22
|
+
%>
|
23
|
+
<% end %>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,4 @@
|
|
1
|
+
Foreman::Application.routes.draw do
|
2
|
+
get 'expired_hosts/select_multiple_expiration' => 'hosts#select_multiple_expiration', as: 'select_multiple_expiration_hosts'
|
3
|
+
post 'expired_hosts/update_multiple_expiration' => 'hosts#update_multiple_expiration', as: 'update_multiple_expiration_hosts'
|
4
|
+
end
|