foreman_dlm 1.1.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|