foreman_dlm 0.1.0 → 2.0.0
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/README.md +18 -6
- data/app/controllers/api/v2/dlmlock_events_controller.rb +42 -0
- data/app/controllers/api/v2/dlmlocks_controller.rb +31 -16
- data/app/controllers/concerns/foreman_dlm/find_host_by_client_cert.rb +7 -13
- data/app/controllers/concerns/foreman_dlm/find_host_by_ip.rb +1 -1
- data/app/controllers/concerns/foreman_dlm/update_checkin_time.rb +22 -0
- data/app/controllers/foreman_dlm/application_controller.rb +19 -0
- data/app/controllers/foreman_dlm/dlmlocks_controller.rb +82 -0
- data/app/helpers/foreman_dlm/dlmlock_helper.rb +33 -0
- data/app/jobs/foreman_dlm/refresh_dlmlock_status.rb +17 -0
- data/app/models/concerns/foreman_dlm/dlm_facet_host_extensions.rb +13 -0
- data/app/models/concerns/foreman_dlm/expirable.rb +36 -0
- data/app/models/concerns/foreman_dlm/host_extensions.rb +21 -2
- data/app/models/concerns/foreman_dlm/host_monitoring_extensions.rb +2 -0
- data/app/models/concerns/foreman_dlm/user_extensions.rb +13 -0
- data/app/models/foreman_dlm/dlm_facet.rb +7 -0
- data/app/models/foreman_dlm/dlmlock/update.rb +9 -0
- data/app/models/foreman_dlm/dlmlock.rb +137 -0
- data/app/models/foreman_dlm/dlmlock_event.rb +23 -0
- data/app/models/host_status/dlmlock_status.rb +44 -0
- data/app/views/api/v2/dlmlock_events/index.json.rabl +2 -0
- data/app/views/api/v2/dlmlocks/show.json.rabl +1 -1
- data/app/views/api/v2/errors/precondition_failed.json.rabl +1 -1
- data/app/views/foreman_dlm/api/v2/dlm_facets/base.json.rabl +1 -0
- data/app/views/foreman_dlm/api/v2/dlm_facets/base_with_root.json.rabl +3 -0
- data/app/views/foreman_dlm/api/v2/dlm_facets/show.json.rabl +3 -0
- data/app/views/foreman_dlm/dlmlocks/_details.html.erb +42 -0
- data/app/views/{dlmlocks → foreman_dlm/dlmlocks}/_list.html.erb +3 -1
- data/app/views/foreman_dlm/dlmlocks/index.html.erb +2 -0
- data/app/views/foreman_dlm/dlmlocks/show.html.erb +10 -0
- data/app/views/{dlmlocks → foreman_dlm/dlmlocks}/welcome.html.erb +2 -2
- data/app/views/hosts/_dlmlocks_tab.html.erb +39 -0
- data/config/routes.rb +20 -13
- data/contrib/systemd/foreman-dlm-expire-events.service +10 -0
- data/contrib/systemd/foreman-dlm-expire-events.timer +8 -0
- data/db/migrate/20170824084100_add_dlmlock.foreman_dlm.rb +1 -1
- data/db/migrate/20180627150003_rename_dlmlock_sti_models.rb +9 -0
- data/db/migrate/20180704162345_add_dlmlock_events.rb +11 -0
- data/db/migrate/20180711090022_add_hosts_fk_to_dlmlocks.rb +5 -0
- data/db/migrate/20180711111903_create_dlm_facets.foreman_dlm.rb +10 -0
- data/db/migrate/20180713113208_update_permissions_for_scoped_models.rb +13 -0
- data/lib/foreman_dlm/engine.rb +58 -19
- data/lib/foreman_dlm/version.rb +1 -1
- data/lib/tasks/dlmlock_events.rake +19 -0
- data/lib/tasks/foreman_dlm_tasks.rake +2 -4
- data/test/controllers/api/v2/dlmlocks_controller_test.rb +73 -52
- data/test/controllers/api/v2/dlmlocks_dlmlock_events_controller_test.rb +81 -0
- data/test/controllers/api/v2/hosts_controller_test.rb +28 -0
- data/test/controllers/find_host_by_client_cert_test.rb +2 -2
- data/test/controllers/foreman_dlm/dlmlocks_test.rb +55 -0
- data/test/controllers/hosts_controller_test.rb +12 -0
- data/test/factories/dlm_facets.rb +6 -0
- data/test/factories/dlmlock.rb +6 -2
- data/test/factories/dlmlock_events.rb +13 -0
- data/test/factories/host.rb +7 -0
- data/test/integration/foreman_dlm/dlmlocks_test.rb +28 -0
- data/test/jobs/refresh_dlmlock_status_test.rb +10 -0
- data/test/models/foreman_dlm/dlm_facet_test.rb +13 -0
- data/test/models/foreman_dlm/dlmlock_event_test.rb +19 -0
- data/test/models/foreman_dlm/dlmlock_test.rb +307 -0
- data/test/models/host_managed_test.rb +41 -0
- data/test/models/host_monitoring_test.rb +1 -1
- data/test/models/host_status/dlmlock_status_test.rb +45 -0
- data/test/models/user_test.rb +5 -0
- data/test/test_plugin_helper.rb +5 -3
- metadata +108 -30
- data/app/controllers/dlmlocks_controller.rb +0 -13
- data/app/models/dlmlock/update.rb +0 -5
- data/app/models/dlmlock.rb +0 -79
- data/app/views/dlmlocks/_details.html.erb +0 -35
- data/app/views/dlmlocks/index.html.erb +0 -2
- data/app/views/dlmlocks/show.html.erb +0 -7
- data/test/controllers/dlmlocks_test.rb +0 -24
- data/test/models/dlmlock_test.rb +0 -201
data/app/models/dlmlock.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
class Dlmlock < ActiveRecord::Base
|
2
|
-
include Authorizable
|
3
|
-
|
4
|
-
def self.humanize_class_name
|
5
|
-
N_('Distributed Lock')
|
6
|
-
end
|
7
|
-
|
8
|
-
belongs_to_host
|
9
|
-
audited
|
10
|
-
|
11
|
-
validates :name, presence: true, uniqueness: true
|
12
|
-
|
13
|
-
scoped_search :on => :name, :complete_value => true, :default_order => true
|
14
|
-
scoped_search :relation => :host, :on => :name, :complete_value => true, :rename => :host
|
15
|
-
scoped_search :on => :type, :complete_value => true, :default_order => true
|
16
|
-
scoped_search :on => :enabled, :complete_value => { :true => true, :false => false }, :only_explicit => true
|
17
|
-
|
18
|
-
attr_accessor :old
|
19
|
-
|
20
|
-
def acquire!(host)
|
21
|
-
atomic_update(nil, host)
|
22
|
-
end
|
23
|
-
|
24
|
-
def release!(host)
|
25
|
-
atomic_update(host, nil)
|
26
|
-
end
|
27
|
-
|
28
|
-
def locked_by?(host)
|
29
|
-
self.host == host
|
30
|
-
end
|
31
|
-
alias_method :acquired_by?, :locked_by?
|
32
|
-
|
33
|
-
def disabled?
|
34
|
-
!enabled?
|
35
|
-
end
|
36
|
-
|
37
|
-
def locked?
|
38
|
-
host.present?
|
39
|
-
end
|
40
|
-
alias_method :taken?, :locked?
|
41
|
-
|
42
|
-
def humanized_type
|
43
|
-
_('Generic Lock')
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def atomic_update(old_host, new_host)
|
49
|
-
changes = {
|
50
|
-
host_id: new_host.try(:id)
|
51
|
-
}
|
52
|
-
self.old = dup
|
53
|
-
num_updated = self.class.where(
|
54
|
-
id: id,
|
55
|
-
host_id: [new_host.try(:id), old_host.try(:id)],
|
56
|
-
enabled: true
|
57
|
-
).update_all(changes.merge(updated_at: DateTime.now))
|
58
|
-
if num_updated > 0
|
59
|
-
reload
|
60
|
-
process_host_change(old_host, new_host, changes)
|
61
|
-
return self
|
62
|
-
end
|
63
|
-
false
|
64
|
-
end
|
65
|
-
|
66
|
-
def process_host_change(old_host, new_host, changes)
|
67
|
-
return if host.try(:id) == old.host.try(:id)
|
68
|
-
write_audit(action: 'update', audited_changes: changes)
|
69
|
-
run_callback(old_host, :unlock) if old.host
|
70
|
-
run_callback(new_host, :lock) if host
|
71
|
-
end
|
72
|
-
|
73
|
-
def run_callback(h, callback)
|
74
|
-
h.run_callbacks callback do
|
75
|
-
logger.debug { "custom hook after_#{callback} on #{h} will be executed if defined." }
|
76
|
-
true
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
<table class="<%= table_css_classes('table-fixed') %>">
|
2
|
-
<thead>
|
3
|
-
<tr>
|
4
|
-
<th><%= _("Owner") %></th>
|
5
|
-
<th><%= _("Initiator") %></th>
|
6
|
-
<th><%= _("Timestamp") %></th>
|
7
|
-
<th><%= _("Enabled") %></th>
|
8
|
-
</tr>
|
9
|
-
</thead>
|
10
|
-
<tbody>
|
11
|
-
<% @dlmlock.audits.includes(:user).reorder(created_at: :desc).each do |audit| %>
|
12
|
-
<% revision = audit.revision %>
|
13
|
-
<tr>
|
14
|
-
<td>
|
15
|
-
<% if revision.host.present? %>
|
16
|
-
<%= link_to_if_authorized(revision.host.name, hash_for_host_path(:id => revision.host)) %>
|
17
|
-
<% end %>
|
18
|
-
</td>
|
19
|
-
<td>
|
20
|
-
<% if audit.user.hidden? %>
|
21
|
-
<em><%= audit.user.name %></em>
|
22
|
-
<% else %>
|
23
|
-
<%= link_to_if_authorized(audit.user.name, hash_for_edit_user_path(audit.user)) %>
|
24
|
-
<% end %>
|
25
|
-
</td>
|
26
|
-
<td>
|
27
|
-
<%= audit.created_at %>
|
28
|
-
</td>
|
29
|
-
<td>
|
30
|
-
<%= revision.enabled? %>
|
31
|
-
</td>
|
32
|
-
</tr>
|
33
|
-
<% end %>
|
34
|
-
</tbody>
|
35
|
-
</table>
|
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'test_plugin_helper'
|
2
|
-
|
3
|
-
class DlmlocksControllerTest < ActionController::TestCase
|
4
|
-
test '#index' do
|
5
|
-
FactoryBot.create(:dlmlock)
|
6
|
-
get :index, {}, set_session_user
|
7
|
-
assert_response :success
|
8
|
-
assert_not_nil assigns('dlmlocks')
|
9
|
-
assert_template 'index'
|
10
|
-
end
|
11
|
-
|
12
|
-
test '#index with no lock shows welcome page' do
|
13
|
-
get :index, {}, set_session_user
|
14
|
-
assert_response :success
|
15
|
-
assert_template 'welcome'
|
16
|
-
end
|
17
|
-
|
18
|
-
test '#show' do
|
19
|
-
dlmlock = FactoryBot.create(:dlmlock)
|
20
|
-
get :show, { :id => dlmlock.id }, set_session_user
|
21
|
-
assert_response :success
|
22
|
-
assert_template 'show'
|
23
|
-
end
|
24
|
-
end
|
data/test/models/dlmlock_test.rb
DELETED
@@ -1,201 +0,0 @@
|
|
1
|
-
require 'test_plugin_helper'
|
2
|
-
|
3
|
-
class DlmlockTest < ActiveSupport::TestCase
|
4
|
-
setup do
|
5
|
-
User.current = users(:admin)
|
6
|
-
end
|
7
|
-
|
8
|
-
subject { FactoryBot.create(:dlmlock) }
|
9
|
-
should validate_presence_of(:name)
|
10
|
-
should validate_uniqueness_of(:name)
|
11
|
-
|
12
|
-
let(:host1) { FactoryBot.create(:host, :managed) }
|
13
|
-
let(:host2) { FactoryBot.create(:host, :managed) }
|
14
|
-
|
15
|
-
class HostWithCallbacks < ::Host::Managed
|
16
|
-
attr_accessor :callbacks
|
17
|
-
|
18
|
-
def initialize(*attributes, &block)
|
19
|
-
super
|
20
|
-
@callbacks = []
|
21
|
-
end
|
22
|
-
|
23
|
-
after_lock :callback1
|
24
|
-
after_unlock :callback2
|
25
|
-
|
26
|
-
def callback1
|
27
|
-
Rails.logger.debug "callback1 executed for #{self} (#{self.class})"
|
28
|
-
callbacks << 'callback1'
|
29
|
-
end
|
30
|
-
|
31
|
-
def callback2
|
32
|
-
Rails.logger.debug "callback2 executed for #{self} (#{self.class})"
|
33
|
-
callbacks << 'callback2'
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
let(:host1_with_callbacks) { HostWithCallbacks.create(:name => 'test1.example.com') }
|
38
|
-
let(:host2_with_callbacks) { HostWithCallbacks.create(:name => 'test2.example.com') }
|
39
|
-
|
40
|
-
context 'a free and enabled DLM lock' do
|
41
|
-
let(:dlmlock) { FactoryBot.create(:dlmlock) }
|
42
|
-
|
43
|
-
test 'should be enabled and unlocked' do
|
44
|
-
assert_equal true, dlmlock.enabled?
|
45
|
-
assert_equal false, dlmlock.disabled?
|
46
|
-
assert_equal false, dlmlock.locked?
|
47
|
-
assert_equal false, dlmlock.taken?
|
48
|
-
end
|
49
|
-
|
50
|
-
test 'can be acquired' do
|
51
|
-
assert_nil dlmlock.host
|
52
|
-
assert dlmlock.acquire!(host1)
|
53
|
-
assert_equal host1, dlmlock.reload.host
|
54
|
-
end
|
55
|
-
|
56
|
-
test 'can be released' do
|
57
|
-
assert_nil dlmlock.host
|
58
|
-
assert dlmlock.release!(host1)
|
59
|
-
assert_nil dlmlock.reload.host
|
60
|
-
end
|
61
|
-
|
62
|
-
test 'records audit change on acquisition by owner' do
|
63
|
-
assert_difference "Audit.where(auditable_type: 'Dlmlock').count" do
|
64
|
-
assert dlmlock.acquire!(host1)
|
65
|
-
end
|
66
|
-
audit_record = dlmlock.audits.last
|
67
|
-
assert_equal 'update', audit_record.action
|
68
|
-
assert_equal({:host_id => host1.id}, audit_record.audited_changes)
|
69
|
-
end
|
70
|
-
|
71
|
-
test 'records no audit change on release' do
|
72
|
-
assert_no_difference "Audit.where(auditable_type: 'Dlmlock').count" do
|
73
|
-
assert dlmlock.release!(host1)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
test 'triggers after_lock callback' do
|
78
|
-
host = HostWithCallbacks.new
|
79
|
-
host.name = 'test.example.com'
|
80
|
-
host.save
|
81
|
-
assert dlmlock.acquire!(host)
|
82
|
-
assert_equal ['callback1'], host.callbacks
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
context 'a free and disabled DLM lock' do
|
87
|
-
let(:dlmlock) { FactoryBot.create(:dlmlock, :enabled => false) }
|
88
|
-
|
89
|
-
test 'should be disabled and unlocked' do
|
90
|
-
assert_equal false, dlmlock.enabled?
|
91
|
-
assert_equal true, dlmlock.disabled?
|
92
|
-
assert_equal false, dlmlock.locked?
|
93
|
-
assert_equal false, dlmlock.taken?
|
94
|
-
end
|
95
|
-
|
96
|
-
test 'can not be acquired' do
|
97
|
-
assert_nil dlmlock.host
|
98
|
-
assert_equal false, dlmlock.acquire!(host1)
|
99
|
-
assert_nil dlmlock.reload.host
|
100
|
-
end
|
101
|
-
|
102
|
-
test 'can not be released' do
|
103
|
-
assert_nil dlmlock.host
|
104
|
-
assert_equal false, dlmlock.release!(host1)
|
105
|
-
assert_nil dlmlock.reload.host
|
106
|
-
end
|
107
|
-
|
108
|
-
test 'triggers no callbacks' do
|
109
|
-
host = HostWithCallbacks.new
|
110
|
-
host.name = 'test.example.com'
|
111
|
-
host.save
|
112
|
-
assert_equal false, dlmlock.release!(host)
|
113
|
-
assert_equal [], host.callbacks
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
context 'an acquired DLM lock' do
|
118
|
-
let(:dlmlock) { FactoryBot.create(:dlmlock, :host => host1) }
|
119
|
-
|
120
|
-
test 'should be enabled and locked' do
|
121
|
-
assert_equal true, dlmlock.enabled?
|
122
|
-
assert_equal false, dlmlock.disabled?
|
123
|
-
assert_equal true, dlmlock.locked?
|
124
|
-
assert_equal true, dlmlock.taken?
|
125
|
-
assert_equal true, dlmlock.locked_by?(host1)
|
126
|
-
assert_equal true, dlmlock.acquired_by?(host1)
|
127
|
-
end
|
128
|
-
|
129
|
-
test 'can be acquired by owner' do
|
130
|
-
assert_equal host1, dlmlock.host
|
131
|
-
assert dlmlock.acquire!(host1)
|
132
|
-
assert_equal host1, dlmlock.reload.host
|
133
|
-
end
|
134
|
-
|
135
|
-
test 'can not be acquired by other host' do
|
136
|
-
assert_equal host1, dlmlock.host
|
137
|
-
assert_equal false, dlmlock.acquire!(host2)
|
138
|
-
assert_equal host1, dlmlock.reload.host
|
139
|
-
end
|
140
|
-
|
141
|
-
test 'can be released by owner' do
|
142
|
-
assert_equal host1, dlmlock.host
|
143
|
-
assert dlmlock.release!(host1)
|
144
|
-
assert_nil dlmlock.reload.host
|
145
|
-
end
|
146
|
-
|
147
|
-
test 'can not be released by other host' do
|
148
|
-
assert_equal host1, dlmlock.host
|
149
|
-
assert_equal false, dlmlock.release!(host2)
|
150
|
-
assert_equal host1, dlmlock.reload.host
|
151
|
-
end
|
152
|
-
|
153
|
-
test 'records audit change on release by owner' do
|
154
|
-
assert_difference "Audit.where(auditable_type: 'Dlmlock').count" do
|
155
|
-
assert dlmlock.release!(host1)
|
156
|
-
end
|
157
|
-
audit_record = dlmlock.audits.last
|
158
|
-
assert_equal 'update', audit_record.action
|
159
|
-
assert_equal({:host_id => nil}, audit_record.audited_changes)
|
160
|
-
end
|
161
|
-
|
162
|
-
test 'records no audit change on acquisition by owner' do
|
163
|
-
assert_no_difference "Audit.where(auditable_type: 'Dlmlock').count" do
|
164
|
-
assert dlmlock.acquire!(host1)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
test 'triggers after_unlock callback on release by owner' do
|
169
|
-
host = HostWithCallbacks.new
|
170
|
-
host.name = 'test.example.com'
|
171
|
-
host.save
|
172
|
-
dlmlock.host = host
|
173
|
-
dlmlock.save
|
174
|
-
assert dlmlock.release!(host)
|
175
|
-
assert_equal ['callback2'], host.callbacks
|
176
|
-
end
|
177
|
-
|
178
|
-
test 'triggers no callbacks on release attempt by other host' do
|
179
|
-
assert host1_with_callbacks
|
180
|
-
assert host2_with_callbacks
|
181
|
-
dlmlock.update(:host => host1_with_callbacks)
|
182
|
-
assert_equal false, dlmlock.release!(host2_with_callbacks)
|
183
|
-
assert_equal [], host1_with_callbacks.callbacks
|
184
|
-
assert_equal [], host2_with_callbacks.callbacks
|
185
|
-
end
|
186
|
-
|
187
|
-
test 'triggers no callbacks on acquiry attempt by owner' do
|
188
|
-
assert host1_with_callbacks
|
189
|
-
dlmlock.update(:host => host1_with_callbacks)
|
190
|
-
assert dlmlock.acquire!(host1_with_callbacks)
|
191
|
-
assert_equal [], host1_with_callbacks.callbacks
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
context 'scoped search' do
|
196
|
-
test 'can be searched by name' do
|
197
|
-
dlmlock = FactoryBot.create(:dlmlock)
|
198
|
-
assert_equal Dlmlock::Update.find(dlmlock.id), Dlmlock.search_for("name ~ #{dlmlock.name}").first
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|