foreman_dlm 1.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 +7 -4
- data/app/controllers/api/v2/dlmlock_events_controller.rb +1 -0
- data/app/controllers/api/v2/dlmlocks_controller.rb +3 -2
- data/app/controllers/concerns/foreman_dlm/find_host_by_client_cert.rb +4 -10
- data/app/controllers/concerns/foreman_dlm/update_checkin_time.rb +1 -0
- data/app/controllers/foreman_dlm/dlmlocks_controller.rb +9 -0
- data/app/helpers/foreman_dlm/dlmlock_helper.rb +2 -0
- data/app/models/concerns/foreman_dlm/expirable.rb +1 -0
- data/app/models/concerns/foreman_dlm/host_extensions.rb +7 -0
- data/app/models/concerns/foreman_dlm/host_monitoring_extensions.rb +2 -0
- data/app/models/foreman_dlm/dlmlock.rb +3 -2
- data/app/views/foreman_dlm/dlmlocks/index.html.erb +1 -1
- data/app/views/foreman_dlm/dlmlocks/show.html.erb +1 -1
- data/app/views/foreman_dlm/dlmlocks/welcome.html.erb +2 -2
- data/app/views/hosts/_dlmlocks_tab.html.erb +3 -3
- data/lib/foreman_dlm/engine.rb +23 -21
- data/lib/foreman_dlm/version.rb +1 -1
- data/test/controllers/api/v2/dlmlocks_controller_test.rb +10 -10
- data/test/controllers/foreman_dlm/dlmlocks_test.rb +2 -2
- data/test/factories/dlmlock.rb +1 -1
- data/test/factories/dlmlock_events.rb +1 -1
- data/test/integration/foreman_dlm/dlmlocks_test.rb +28 -0
- data/test/models/foreman_dlm/dlmlock_test.rb +15 -7
- data/test/models/host_managed_test.rb +18 -0
- data/test/models/host_status/dlmlock_status_test.rb +2 -6
- data/test/test_plugin_helper.rb +4 -0
- metadata +57 -27
- data/app/models/settings/dlm.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46b88d4ab255520440c5a8aeb4222e8ab62e167027ca0a833eaa03bf4ee32885
|
4
|
+
data.tar.gz: 9b953cde9907b2e7be6282aedbf44fad05d447f13d97e420c62ffd47a3ccf685
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f07de80a511db25bbfdc37d01726a611678b8be5c360c1020ad6ff3e69fdac0d269fe2312fbed24770d8ebec21f05148eb5d629ea69e8b6f2298597adfdea1f
|
7
|
+
data.tar.gz: 9ced134c94780300383e6096e968fdadf1035ac6323f053a0ffcffa8027c660447ce1fd49c830a9d9c103389c7412021e96243fe63e8581fbe743f314b8a605d
|
data/README.md
CHANGED
@@ -14,6 +14,7 @@ With this plugin servers can acquire a lock in Foreman to ensure only one server
|
|
14
14
|
| --------------- | -------------- |
|
15
15
|
| >= 1.15 | ~> 0.1 |
|
16
16
|
| >= 1.17 | ~> 1.0 |
|
17
|
+
| >= 3.0 | ~> 2.0 |
|
17
18
|
|
18
19
|
## Installation
|
19
20
|
|
@@ -34,6 +35,7 @@ Use the HTTP method `GET` to show a lock, `PUT` to acquire a lock and `DELETE` t
|
|
34
35
|
Foreman will respond with the HTTP status code `200 OK` if the action was successful and `412 Precondition Failed` if the lock could not be acquired or release. This may happen, if the lock is taken by another host.
|
35
36
|
|
36
37
|
To process the HTTP status code in a bash script, you can do something like this:
|
38
|
+
|
37
39
|
```
|
38
40
|
curl --write-out %{http_code} -H 'Content-Type: application/json' -sS -o /dev/null -X PUT --key $(puppet config print hostprivkey) --cert $(puppet config print hostcert) https://foreman.example.com/api/dlmlocks/test/lock
|
39
41
|
```
|
@@ -59,17 +61,19 @@ $ brew link curl --force
|
|
59
61
|
```
|
60
62
|
|
61
63
|
After that `curl --version` changes from
|
64
|
+
|
62
65
|
```
|
63
66
|
$ curl --version
|
64
67
|
curl 7.54.0 (x86_64-apple-darwin16.0) libcurl/7.54.0 SecureTransport zlib/1.2.8
|
65
68
|
```
|
69
|
+
|
66
70
|
to
|
71
|
+
|
67
72
|
```
|
68
73
|
$ curl --version
|
69
74
|
curl 7.56.1 (x86_64-apple-darwin16.7.0) libcurl/7.56.1 OpenSSL/1.0.2m zlib/1.2.8
|
70
75
|
```
|
71
76
|
|
72
|
-
|
73
77
|
## Contributing
|
74
78
|
|
75
79
|
Fork and send a Pull Request. Thanks!
|
@@ -85,9 +89,8 @@ the Free Software Foundation, either version 3 of the License, or
|
|
85
89
|
|
86
90
|
This program is distributed in the hope that it will be useful,
|
87
91
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
88
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
92
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
89
93
|
GNU General Public License for more details.
|
90
94
|
|
91
95
|
You should have received a copy of the GNU General Public License
|
92
|
-
along with this program.
|
93
|
-
|
96
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
@@ -73,7 +73,7 @@ module Api
|
|
73
73
|
|
74
74
|
== Authentication & Host Identification
|
75
75
|
The host is authenticated via a client certificate and identified via the CN of that certificate.
|
76
|
-
|
76
|
+
DOCS
|
77
77
|
|
78
78
|
def acquire
|
79
79
|
process_lock_response @dlmlock.acquire!(@host)
|
@@ -91,7 +91,7 @@ module Api
|
|
91
91
|
|
92
92
|
== Authentication & Host Identification
|
93
93
|
The host is authenticated via a client certificate and identified via the CN of that certificate.
|
94
|
-
|
94
|
+
DOCS
|
95
95
|
|
96
96
|
def release
|
97
97
|
process_lock_response @dlmlock.release!(@host)
|
@@ -108,6 +108,7 @@ module Api
|
|
108
108
|
rescue ActiveRecord::RecordNotFound
|
109
109
|
result = scope.find_by(:name => id)
|
110
110
|
raise ActiveRecord::RecordNotFound unless result
|
111
|
+
|
111
112
|
result
|
112
113
|
end
|
113
114
|
|
@@ -46,17 +46,11 @@ module ForemanDlm
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def get_client_cert_hostname
|
49
|
-
|
50
|
-
unless
|
51
|
-
logger.info { "Client certificate is invalid: #{verify}" }
|
52
|
-
return
|
53
|
-
end
|
54
|
-
|
55
|
-
dn = request.env[Setting[:ssl_client_dn_env]]
|
56
|
-
return unless dn && dn =~ /CN=([^\s\/,]+)/i
|
49
|
+
client_certificate = Foreman::ClientCertificate.new(request: request)
|
50
|
+
return unless client_certificate.verified?
|
57
51
|
|
58
|
-
hostname =
|
59
|
-
logger.debug "Extracted hostname '#{hostname}' from client certificate."
|
52
|
+
hostname = client_certificate.subject
|
53
|
+
logger.debug "Extracted hostname '#{hostname}' from client certificate." if hostname
|
60
54
|
hostname
|
61
55
|
end
|
62
56
|
end
|
@@ -13,6 +13,7 @@ module ForemanDlm
|
|
13
13
|
# Updates the last_checkin timestamp of a user
|
14
14
|
def update_detected_host_checkin_time
|
15
15
|
return unless @detected_host
|
16
|
+
|
16
17
|
facet = @detected_host.dlm_facet || @detected_host.build_dlm_facet
|
17
18
|
facet.save unless facet.persisted?
|
18
19
|
facet.touch(:last_checkin_at)
|
@@ -59,6 +59,15 @@ module ForemanDlm
|
|
59
59
|
ForemanDlm::Dlmlock
|
60
60
|
end
|
61
61
|
|
62
|
+
# see https://projects.theforeman.org/issues/25976
|
63
|
+
# can be removed for Foreman 1.22+
|
64
|
+
def auto_complete_controller_name
|
65
|
+
current_version = Gem::Version.new(Foreman::Version.new.notag)
|
66
|
+
return '/foreman_dlm/dlmlocks' if current_version >= Gem::Version.new('1.20') && current_version < Gem::Version.new('1.22')
|
67
|
+
|
68
|
+
controller_name
|
69
|
+
end
|
70
|
+
|
62
71
|
private
|
63
72
|
|
64
73
|
def action_permission
|
@@ -3,12 +3,14 @@ module ForemanDlm
|
|
3
3
|
def dlmlock_status_icon_class(lock)
|
4
4
|
return 'ban' if lock.disabled?
|
5
5
|
return 'lock' if lock.taken?
|
6
|
+
|
6
7
|
'unlock'
|
7
8
|
end
|
8
9
|
|
9
10
|
def dlmlock_status_icon_color_class(lock)
|
10
11
|
return 'text-danger' if lock.disabled?
|
11
12
|
return 'text-success' if lock.taken?
|
13
|
+
|
12
14
|
'text-info'
|
13
15
|
end
|
14
16
|
|
@@ -19,6 +19,13 @@ module ForemanDlm
|
|
19
19
|
define_model_callbacks :unlock, :only => :after
|
20
20
|
end
|
21
21
|
|
22
|
+
def can_acquire_update_locks?
|
23
|
+
param = host_param('can_acquire_update_locks')
|
24
|
+
return true if param.blank?
|
25
|
+
|
26
|
+
Foreman::Cast.to_bool(param)
|
27
|
+
end
|
28
|
+
|
22
29
|
def refresh_dlmlock_status
|
23
30
|
refresh_statuses([HostStatus::DlmlockStatus])
|
24
31
|
end
|
@@ -9,6 +9,7 @@ module ForemanDlm
|
|
9
9
|
|
10
10
|
def add_lock_monitoring_downtime
|
11
11
|
return unless monitored?
|
12
|
+
|
12
13
|
logger.info "Setting Monitoring downtime for #{self}"
|
13
14
|
monitoring.set_downtime_host(self, lock_monitoring_downtime_options)
|
14
15
|
true
|
@@ -18,6 +19,7 @@ module ForemanDlm
|
|
18
19
|
|
19
20
|
def remove_lock_monitoring_downtime
|
20
21
|
return unless monitored?
|
22
|
+
|
21
23
|
logger.info "Deleting Monitoring downtime for #{self}"
|
22
24
|
monitoring.del_downtime_host(self, lock_monitoring_downtime_options)
|
23
25
|
true
|
@@ -7,14 +7,13 @@ module ForemanDlm
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def self.dlm_stale_time
|
10
|
-
(Setting
|
10
|
+
(Setting[:dlm_stale_time] || 4).hours
|
11
11
|
end
|
12
12
|
|
13
13
|
belongs_to_host
|
14
14
|
|
15
15
|
has_many :dlmlock_events,
|
16
16
|
class_name: '::ForemanDlm::DlmlockEvent',
|
17
|
-
foreign_key: 'dlmlock_id',
|
18
17
|
dependent: :destroy,
|
19
18
|
inverse_of: :dlmlock
|
20
19
|
|
@@ -46,6 +45,8 @@ module ForemanDlm
|
|
46
45
|
attr_accessor :old
|
47
46
|
|
48
47
|
def acquire!(host)
|
48
|
+
return false unless host.can_acquire_update_locks?
|
49
|
+
|
49
50
|
result = atomic_update(nil, host)
|
50
51
|
ForemanDlm::RefreshDlmlockStatus.set(wait: self.class.dlm_stale_time).perform_later([host.id]) if result
|
51
52
|
result
|
@@ -1,2 +1,2 @@
|
|
1
|
-
<% title _(
|
1
|
+
<% title _('Distributed Locks') %>
|
2
2
|
<%= render :partial => 'list' %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<% title @dlmlock.name %>
|
2
2
|
<% breadcrumbs(
|
3
|
-
|
3
|
+
resource_url: api_dlmlocks_path
|
4
4
|
) if respond_to?(:breadcrumbs) # Requires Foreman >= 1.18 %>
|
5
5
|
|
6
6
|
<%= title_actions link_to(_('Back'), foreman_dlm_dlmlocks_path, :class => 'btn btn-default'),
|
@@ -6,9 +6,9 @@
|
|
6
6
|
<p>
|
7
7
|
<%= _('You don\'t seem to have any locks.') %></br>
|
8
8
|
<%= _('The distributed lock manager allows you to automatically schedule system updates across a cluster of hosts.') %>
|
9
|
-
<%= link_to _('Learn more about this in the documentation.'), 'https://github.com/
|
9
|
+
<%= link_to _('Learn more about this in the documentation.'), 'https://github.com/dm-drogeriemarkt/foreman_dlm', :rel => "external" %>.
|
10
10
|
</p>
|
11
11
|
<div class="blank-slate-pf-main-action">
|
12
|
-
<%= link_to _('Documentation'), 'https://github.com/
|
12
|
+
<%= link_to _('Documentation'), 'https://github.com/dm-drogeriemarkt/foreman_dlm', :rel => 'external', :class => 'btn btn-primary btn-lg' %>
|
13
13
|
</div>
|
14
14
|
</div>
|
@@ -2,14 +2,14 @@
|
|
2
2
|
<%= alert class: 'alert-info',
|
3
3
|
header: '',
|
4
4
|
text: n_(
|
5
|
-
'This host holds
|
5
|
+
'This host holds one lock.',
|
6
6
|
'This host holds %s locks.',
|
7
7
|
@host.dlmlocks.count
|
8
8
|
) % @host.dlmlocks.count
|
9
9
|
%>
|
10
10
|
<% end %>
|
11
11
|
|
12
|
-
<table class="<%= table_css_classes %>
|
12
|
+
<table class="<%= table_css_classes %>">
|
13
13
|
<thead>
|
14
14
|
<tr>
|
15
15
|
<th colspan="2"><%= _('Locks') %></th>
|
@@ -17,7 +17,7 @@
|
|
17
17
|
</thead>
|
18
18
|
<tbody>
|
19
19
|
<tr>
|
20
|
-
<td><%= _('Last
|
20
|
+
<td class="text-nowrap"><%= _('Last check-in') %></td>
|
21
21
|
<td><%= @host.dlm_facet && @host.dlm_facet.last_checkin_at ? date_time_relative(@host.dlm_facet.last_checkin_at) : _('N/A') %></td>
|
22
22
|
</tr>
|
23
23
|
<tr>
|
data/lib/foreman_dlm/engine.rb
CHANGED
@@ -6,14 +6,6 @@ module ForemanDlm
|
|
6
6
|
config.autoload_paths += Dir["#{config.root}/app/models/concerns"]
|
7
7
|
config.autoload_paths += Dir["#{config.root}/app/jobs"]
|
8
8
|
|
9
|
-
initializer 'foreman_dlm.load_default_settings', before: :load_config_initializers do
|
10
|
-
require_dependency File.expand_path('../../app/models/settings/dlm.rb', __dir__) if begin
|
11
|
-
Setting.table_exists?
|
12
|
-
rescue StandardError
|
13
|
-
(false)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
9
|
# Add any db migrations
|
18
10
|
initializer 'foreman_dlm.load_app_instance_data' do |app|
|
19
11
|
ForemanDlm::Engine.paths['db/migrate'].existent.each do |path|
|
@@ -23,10 +15,21 @@ module ForemanDlm
|
|
23
15
|
|
24
16
|
initializer 'foreman_dlm.register_plugin', :before => :finisher_hook do |_app|
|
25
17
|
Foreman::Plugin.register :foreman_dlm do
|
26
|
-
requires_foreman '>=
|
18
|
+
requires_foreman '>= 3.0'
|
27
19
|
|
28
20
|
apipie_documented_controllers ["#{ForemanDlm::Engine.root}/app/controllers/api/v2/*.rb"]
|
29
21
|
|
22
|
+
settings do
|
23
|
+
category(:general) do
|
24
|
+
setting('dlm_stale_time',
|
25
|
+
type: :integer,
|
26
|
+
default: 4,
|
27
|
+
description: N_('Number of hours after which locked Distributed Lock is stale'),
|
28
|
+
full_name: N_('Distributed Lock stale time'),
|
29
|
+
validate: { numericality: { greater_than: 0 } })
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
30
33
|
# Add permissions
|
31
34
|
security_block :foreman_dlm do
|
32
35
|
permission :view_dlmlocks, {
|
@@ -58,10 +61,11 @@ module ForemanDlm
|
|
58
61
|
:create_dlmlocks,
|
59
62
|
:edit_dlmlocks,
|
60
63
|
:destroy_dlmlocks,
|
61
|
-
:view_dlmlock_events]
|
64
|
+
:view_dlmlock_events],
|
65
|
+
'Role granting full access permissions to distributed locks'
|
62
66
|
|
63
67
|
# add menu entry
|
64
|
-
menu :top_menu, :
|
68
|
+
menu :top_menu, :foreman_dlm_dlmlocks,
|
65
69
|
url_hash: { controller: :'foreman_dlm/dlmlocks', action: :index },
|
66
70
|
caption: N_('Distributed Locks'),
|
67
71
|
parent: :monitor_menu,
|
@@ -86,19 +90,17 @@ module ForemanDlm
|
|
86
90
|
|
87
91
|
# Include concerns in this config.to_prepare block
|
88
92
|
config.to_prepare do
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
Rails.logger.warn "ForemanDlm: skipping engine hook (#{e})"
|
97
|
-
end
|
93
|
+
Host::Managed.include ForemanDlm::HostExtensions
|
94
|
+
User.include ForemanDlm::UserExtensions
|
95
|
+
Host::Managed.include ForemanDlm::DlmFacetHostExtensions
|
96
|
+
|
97
|
+
Host::Managed.include ForemanDlm::HostMonitoringExtensions if ForemanDlm.with_monitoring?
|
98
|
+
rescue StandardError => e
|
99
|
+
Rails.logger.warn "ForemanDlm: skipping engine hook (#{e})"
|
98
100
|
end
|
99
101
|
|
100
102
|
initializer 'foreman_dlm.register_gettext', after: :load_config_initializers do |_app|
|
101
|
-
locale_dir = File.join(File.expand_path('
|
103
|
+
locale_dir = File.join(File.expand_path('../..', __dir__), 'locale')
|
102
104
|
locale_domain = 'foreman_dlm'
|
103
105
|
Foreman::Gettext::Support.add_text_domain locale_domain, locale_dir
|
104
106
|
end
|
data/lib/foreman_dlm/version.rb
CHANGED
@@ -44,7 +44,7 @@ class Api::V2::DlmlocksControllerTest < ActionController::TestCase
|
|
44
44
|
get :show, params: { :id => dlmlock.to_param }
|
45
45
|
assert_response :success
|
46
46
|
body = ActiveSupport::JSON.decode(@response.body)
|
47
|
-
|
47
|
+
assert_not_empty body
|
48
48
|
assert_equal dlmlock.name, body['name']
|
49
49
|
assert_equal dlmlock.type, body['type']
|
50
50
|
assert_equal true, body['enabled']
|
@@ -56,7 +56,7 @@ class Api::V2::DlmlocksControllerTest < ActionController::TestCase
|
|
56
56
|
get :show, params: { :id => dlmlock.to_param }
|
57
57
|
assert_response :success
|
58
58
|
body = ActiveSupport::JSON.decode(@response.body)
|
59
|
-
|
59
|
+
assert_not_empty body
|
60
60
|
assert_equal dlmlock.name, body['name']
|
61
61
|
assert_equal dlmlock.type, body['type']
|
62
62
|
assert_equal false, body['enabled']
|
@@ -68,13 +68,13 @@ class Api::V2::DlmlocksControllerTest < ActionController::TestCase
|
|
68
68
|
get :show, params: { :id => dlmlock.name }
|
69
69
|
assert_response :success
|
70
70
|
body = ActiveSupport::JSON.decode(@response.body)
|
71
|
-
|
71
|
+
assert_not_empty body
|
72
72
|
assert_equal dlmlock.id, body['id']
|
73
73
|
assert_equal dlmlock.name, body['name']
|
74
74
|
host = body['host']
|
75
75
|
assert host
|
76
76
|
assert_equal host1.name, host['name']
|
77
|
-
|
77
|
+
assert_not host.key?('self')
|
78
78
|
end
|
79
79
|
|
80
80
|
test 'should not find dlmlock with invalid id' do
|
@@ -178,7 +178,7 @@ class Api::V2::DlmlocksControllerTest < ActionController::TestCase
|
|
178
178
|
get :show, params: { :id => dlmlock.to_param }
|
179
179
|
assert_response :success
|
180
180
|
body = ActiveSupport::JSON.decode(@response.body)
|
181
|
-
|
181
|
+
assert_not_empty body
|
182
182
|
assert_equal dlmlock.name, body['name']
|
183
183
|
assert_equal dlmlock.type, body['type']
|
184
184
|
assert_equal true, body['enabled']
|
@@ -191,7 +191,7 @@ class Api::V2::DlmlocksControllerTest < ActionController::TestCase
|
|
191
191
|
get :show, params: { :id => dlmlock.to_param }
|
192
192
|
assert_response :success
|
193
193
|
body = ActiveSupport::JSON.decode(@response.body)
|
194
|
-
|
194
|
+
assert_not_empty body
|
195
195
|
assert_equal dlmlock.name, body['name']
|
196
196
|
assert_equal dlmlock.type, body['type']
|
197
197
|
assert_equal true, body['enabled']
|
@@ -207,7 +207,7 @@ class Api::V2::DlmlocksControllerTest < ActionController::TestCase
|
|
207
207
|
get :show, params: { :id => dlmlock.to_param }
|
208
208
|
assert_response :success
|
209
209
|
body = ActiveSupport::JSON.decode(@response.body)
|
210
|
-
|
210
|
+
assert_not_empty body
|
211
211
|
assert_equal dlmlock.name, body['name']
|
212
212
|
assert_equal dlmlock.type, body['type']
|
213
213
|
assert_equal true, body['enabled']
|
@@ -220,7 +220,7 @@ class Api::V2::DlmlocksControllerTest < ActionController::TestCase
|
|
220
220
|
|
221
221
|
test 'should update checkin time' do
|
222
222
|
dlmlock = as_admin { FactoryBot.create(:dlmlock) }
|
223
|
-
|
223
|
+
assert_not as_admin { host1.dlm_facet }
|
224
224
|
put :show, params: { :id => dlmlock.to_param }
|
225
225
|
assert as_admin { host1.reload.dlm_facet.last_checkin_at }
|
226
226
|
end
|
@@ -260,7 +260,7 @@ class Api::V2::DlmlocksControllerTest < ActionController::TestCase
|
|
260
260
|
|
261
261
|
test 'should update checkin time' do
|
262
262
|
dlmlock = as_admin { FactoryBot.create(:dlmlock) }
|
263
|
-
|
263
|
+
assert_not as_admin { host1.dlm_facet }
|
264
264
|
put :acquire, params: { :id => dlmlock.to_param }
|
265
265
|
assert as_admin { host1.reload.dlm_facet.last_checkin_at }
|
266
266
|
end
|
@@ -300,7 +300,7 @@ class Api::V2::DlmlocksControllerTest < ActionController::TestCase
|
|
300
300
|
|
301
301
|
test 'should update checkin time' do
|
302
302
|
dlmlock = as_admin { FactoryBot.create(:dlmlock) }
|
303
|
-
|
303
|
+
assert_not as_admin { host1.dlm_facet }
|
304
304
|
put :release, params: { :id => dlmlock.to_param }
|
305
305
|
assert as_admin { host1.reload.dlm_facet.last_checkin_at }
|
306
306
|
end
|
@@ -27,7 +27,7 @@ module ForemanDlm
|
|
27
27
|
dlmlock = FactoryBot.create(:dlmlock)
|
28
28
|
delete :destroy, params: { :id => dlmlock.id }, session: set_session_user
|
29
29
|
assert_redirected_to foreman_dlm_dlmlocks_url
|
30
|
-
|
30
|
+
assert_not Dlmlock.exists?(dlmlock.id)
|
31
31
|
end
|
32
32
|
|
33
33
|
test '#enable' do
|
@@ -49,7 +49,7 @@ module ForemanDlm
|
|
49
49
|
dlmlock = FactoryBot.create(:dlmlock, host: host)
|
50
50
|
put :release, params: { :id => dlmlock.id }, session: set_session_user
|
51
51
|
assert_redirected_to foreman_dlm_dlmlocks_url
|
52
|
-
|
52
|
+
assert_not dlmlock.reload.taken?
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
data/test/factories/dlmlock.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_plugin_helper'
|
4
|
+
require 'integration_test_helper'
|
5
|
+
|
6
|
+
class DlmlocksTest < IntegrationTestWithJavascript
|
7
|
+
setup do
|
8
|
+
User.current = users(:admin)
|
9
|
+
end
|
10
|
+
|
11
|
+
test 'the index page works' do
|
12
|
+
FactoryBot.create_list(:dlmlock, 10)
|
13
|
+
assert_index_page(foreman_dlm_dlmlocks_path, 'Distributed Locks')
|
14
|
+
end
|
15
|
+
|
16
|
+
test 'the search bar has autocomplete' do
|
17
|
+
skip if Gem::Version.new(Foreman::Version.new.notag) < Gem::Version.new('1.20')
|
18
|
+
FactoryBot.create_list(:dlmlock, 10)
|
19
|
+
|
20
|
+
visit foreman_dlm_dlmlocks_path
|
21
|
+
|
22
|
+
search_bar = page.first('#search-bar')
|
23
|
+
search_bar.first('input').set('ho')
|
24
|
+
|
25
|
+
list = search_bar.find_all('a.dropdown-item').map(&:text)
|
26
|
+
assert_includes list, 'host'
|
27
|
+
end
|
28
|
+
end
|
@@ -82,6 +82,18 @@ module ForemanDlm
|
|
82
82
|
assert dlmlock.acquire!(host)
|
83
83
|
assert_equal ['callback1'], host.callbacks
|
84
84
|
end
|
85
|
+
|
86
|
+
context 'with a parameter disabeling the locking' do
|
87
|
+
setup do
|
88
|
+
FactoryBot.create(:host_parameter, host: host1, name: 'can_acquire_update_locks', value: 'false')
|
89
|
+
end
|
90
|
+
|
91
|
+
test 'can not be acquired' do
|
92
|
+
assert_nil dlmlock.host
|
93
|
+
assert_not dlmlock.acquire!(host1)
|
94
|
+
assert_nil dlmlock.reload.host
|
95
|
+
end
|
96
|
+
end
|
85
97
|
end
|
86
98
|
|
87
99
|
context 'a free and disabled DLM lock' do
|
@@ -212,15 +224,11 @@ module ForemanDlm
|
|
212
224
|
not_locked = FactoryBot.create(:dlmlock)
|
213
225
|
|
214
226
|
assert_includes subject, locked
|
215
|
-
|
227
|
+
assert_not_includes subject, not_locked
|
216
228
|
end
|
217
229
|
end
|
218
230
|
|
219
231
|
describe '#stale' do
|
220
|
-
setup do
|
221
|
-
FactoryBot.create(:setting, category: Setting::General, name: 'dlm_stale_time', value: 4)
|
222
|
-
end
|
223
|
-
|
224
232
|
subject { Dlmlock.stale }
|
225
233
|
|
226
234
|
it 'includes only Distributed Locks that are stale' do
|
@@ -232,8 +240,8 @@ module ForemanDlm
|
|
232
240
|
not_locked = FactoryBot.create(:dlmlock)
|
233
241
|
|
234
242
|
assert_includes subject, stale
|
235
|
-
|
236
|
-
|
243
|
+
assert_not_includes subject, not_stale
|
244
|
+
assert_not_includes subject, not_locked
|
237
245
|
end
|
238
246
|
end
|
239
247
|
end
|
@@ -6,6 +6,24 @@ module Host
|
|
6
6
|
should have_many(:dlmlock_events)
|
7
7
|
should have_one(:dlm_facet)
|
8
8
|
|
9
|
+
describe '#can_acquire_update_locks?' do
|
10
|
+
let(:host) { FactoryBot.create(:host, :managed) }
|
11
|
+
|
12
|
+
it 'should be true without a host parameter' do
|
13
|
+
assert host.can_acquire_update_locks?
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should be true if parameter is true' do
|
17
|
+
FactoryBot.create(:host_parameter, host: host, name: 'can_acquire_update_locks', value: 'true')
|
18
|
+
assert host.can_acquire_update_locks?
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should be false if parameter is false' do
|
22
|
+
FactoryBot.create(:host_parameter, host: host, name: 'can_acquire_update_locks', value: 'false')
|
23
|
+
assert_not host.can_acquire_update_locks?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
9
27
|
context 'scoped search on' do
|
10
28
|
context 'a host' do
|
11
29
|
let(:host) { FactoryBot.create(:host, :with_dlm_facet) }
|
@@ -3,10 +3,6 @@
|
|
3
3
|
require 'test_plugin_helper'
|
4
4
|
|
5
5
|
class DlmlockStatusTest < ActiveSupport::TestCase
|
6
|
-
setup do
|
7
|
-
FactoryBot.create(:setting, category: Setting::General, name: 'dlm_stale_time', value: 4)
|
8
|
-
end
|
9
|
-
|
10
6
|
let(:host) { FactoryBot.create(:host, :managed) }
|
11
7
|
|
12
8
|
describe '#to_status' do
|
@@ -17,7 +13,7 @@ class DlmlockStatusTest < ActiveSupport::TestCase
|
|
17
13
|
FactoryBot.create(:dlmlock, :locked, host: host, updated_at: now - 5.hours)
|
18
14
|
status = host.get_status(HostStatus::DlmlockStatus)
|
19
15
|
|
20
|
-
|
16
|
+
assert_not_empty host.dlmlocks.stale
|
21
17
|
assert_equal HostStatus::DlmlockStatus::STALE, status.to_status
|
22
18
|
end
|
23
19
|
end
|
@@ -35,7 +31,7 @@ class DlmlockStatusTest < ActiveSupport::TestCase
|
|
35
31
|
FactoryBot.create(:dlmlock, host: host)
|
36
32
|
status = host.get_status(HostStatus::DlmlockStatus)
|
37
33
|
|
38
|
-
|
34
|
+
assert_not_empty host.dlmlocks
|
39
35
|
assert_equal true, status.relevant?
|
40
36
|
end
|
41
37
|
|
data/test/test_plugin_helper.rb
CHANGED
@@ -3,5 +3,9 @@ require 'test_helper'
|
|
3
3
|
|
4
4
|
# Add plugin to FactoryBot's paths
|
5
5
|
FactoryBot.definition_file_paths << File.join(File.dirname(__FILE__), 'factories')
|
6
|
+
|
7
|
+
# Add factories of external plugin dependencies
|
6
8
|
FactoryBot.definition_file_paths << "#{ForemanMonitoring::Engine.root}/test/factories" if ForemanDlm.with_monitoring?
|
9
|
+
|
10
|
+
# Reload factory paths
|
7
11
|
FactoryBot.reload
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_dlm
|
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: 2022-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rdoc
|
@@ -28,16 +28,44 @@ 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:
|
33
|
+
version: 1.25.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:
|
40
|
+
version: 1.25.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop-performance
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.13.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.13.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop-rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.9.1
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.9.1
|
41
69
|
description: Adds a Distributed Lock Manager to Foreman. This enables painless system
|
42
70
|
updates for clusters.
|
43
71
|
email:
|
@@ -69,7 +97,6 @@ files:
|
|
69
97
|
- app/models/foreman_dlm/dlmlock/update.rb
|
70
98
|
- app/models/foreman_dlm/dlmlock_event.rb
|
71
99
|
- app/models/host_status/dlmlock_status.rb
|
72
|
-
- app/models/settings/dlm.rb
|
73
100
|
- app/views/api/v2/dlmlock_events/index.json.rabl
|
74
101
|
- app/views/api/v2/dlmlocks/acquire.json.rabl
|
75
102
|
- app/views/api/v2/dlmlocks/base.json.rabl
|
@@ -117,6 +144,7 @@ files:
|
|
117
144
|
- test/factories/dlmlock.rb
|
118
145
|
- test/factories/dlmlock_events.rb
|
119
146
|
- test/factories/host.rb
|
147
|
+
- test/integration/foreman_dlm/dlmlocks_test.rb
|
120
148
|
- test/jobs/refresh_dlmlock_status_test.rb
|
121
149
|
- test/models/foreman_dlm/dlm_facet_test.rb
|
122
150
|
- test/models/foreman_dlm/dlmlock_event_test.rb
|
@@ -129,8 +157,10 @@ files:
|
|
129
157
|
homepage: https://github.com/dm-drogeriemarkt/foreman_dlm
|
130
158
|
licenses:
|
131
159
|
- GPL-3.0
|
132
|
-
metadata:
|
133
|
-
|
160
|
+
metadata:
|
161
|
+
rubygems_mfa_required: 'true'
|
162
|
+
is_foreman_plugin: 'true'
|
163
|
+
post_install_message:
|
134
164
|
rdoc_options: []
|
135
165
|
require_paths:
|
136
166
|
- lib
|
@@ -145,28 +175,28 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
175
|
- !ruby/object:Gem::Version
|
146
176
|
version: '0'
|
147
177
|
requirements: []
|
148
|
-
|
149
|
-
|
150
|
-
signing_key:
|
178
|
+
rubygems_version: 3.3.3
|
179
|
+
signing_key:
|
151
180
|
specification_version: 4
|
152
181
|
summary: Distributed Lock Manager for Foreman.
|
153
182
|
test_files:
|
154
|
-
- test/
|
155
|
-
- test/
|
183
|
+
- test/controllers/api/v2/dlmlocks_controller_test.rb
|
184
|
+
- test/controllers/api/v2/dlmlocks_dlmlock_events_controller_test.rb
|
185
|
+
- test/controllers/api/v2/hosts_controller_test.rb
|
186
|
+
- test/controllers/find_host_by_client_cert_test.rb
|
187
|
+
- test/controllers/foreman_dlm/dlmlocks_test.rb
|
188
|
+
- test/controllers/hosts_controller_test.rb
|
189
|
+
- test/factories/dlm_facets.rb
|
190
|
+
- test/factories/dlmlock.rb
|
191
|
+
- test/factories/dlmlock_events.rb
|
192
|
+
- test/factories/host.rb
|
193
|
+
- test/integration/foreman_dlm/dlmlocks_test.rb
|
194
|
+
- test/jobs/refresh_dlmlock_status_test.rb
|
156
195
|
- test/models/foreman_dlm/dlm_facet_test.rb
|
196
|
+
- test/models/foreman_dlm/dlmlock_event_test.rb
|
157
197
|
- test/models/foreman_dlm/dlmlock_test.rb
|
158
|
-
- test/models/
|
198
|
+
- test/models/host_managed_test.rb
|
159
199
|
- test/models/host_monitoring_test.rb
|
200
|
+
- test/models/host_status/dlmlock_status_test.rb
|
160
201
|
- test/models/user_test.rb
|
161
|
-
- test/factories/dlm_facets.rb
|
162
|
-
- test/factories/host.rb
|
163
|
-
- test/factories/dlmlock_events.rb
|
164
|
-
- test/factories/dlmlock.rb
|
165
202
|
- test/test_plugin_helper.rb
|
166
|
-
- test/jobs/refresh_dlmlock_status_test.rb
|
167
|
-
- test/controllers/foreman_dlm/dlmlocks_test.rb
|
168
|
-
- test/controllers/api/v2/dlmlocks_controller_test.rb
|
169
|
-
- test/controllers/api/v2/hosts_controller_test.rb
|
170
|
-
- test/controllers/api/v2/dlmlocks_dlmlock_events_controller_test.rb
|
171
|
-
- test/controllers/hosts_controller_test.rb
|
172
|
-
- test/controllers/find_host_by_client_cert_test.rb
|
data/app/models/settings/dlm.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
class Setting
|
2
|
-
class Dlm < ::Setting
|
3
|
-
def self.load_defaults
|
4
|
-
return unless ActiveRecord::Base.connection.table_exists?('settings')
|
5
|
-
return unless super
|
6
|
-
|
7
|
-
Setting.transaction do
|
8
|
-
[
|
9
|
-
set('dlm_stale_time', N_('Number of hours after which locked Distributed Lock is stale'), 4, N_('Distributed Lock stale time'))
|
10
|
-
].compact.each { |s| Setting::General.create s.update(category: 'Setting::General') }
|
11
|
-
end
|
12
|
-
|
13
|
-
true
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.humanized_category
|
17
|
-
N_('Distributed Locks')
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|