foreman_remote_execution 3.1.0 → 3.2.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/app/helpers/job_invocations_chart_helper.rb +2 -0
- data/app/helpers/remote_execution_helper.rb +6 -2
- data/app/lib/proxy_api/remote_execution_ssh.rb +6 -0
- data/app/models/concerns/foreman_remote_execution/orchestration/ssh.rb +58 -0
- data/app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb +4 -0
- data/app/models/host_status/execution_status.rb +9 -1
- data/app/views/job_invocations/_card_results.html.erb +1 -0
- data/app/views/job_invocations/_host_status_td.html.erb +1 -1
- data/app/views/job_invocations/_tab_overview.html.erb +1 -1
- data/app/views/job_invocations/show.html.erb +1 -1
- data/config/routes.rb +2 -1
- data/foreman_remote_execution.gemspec +1 -1
- data/lib/foreman_remote_execution/engine.rb +2 -0
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/test/functional/job_invocations_controller_test.rb +12 -0
- data/test/models/orchestration/ssh_test.rb +24 -0
- data/test/unit/remote_execution_provider_test.rb +4 -1
- data/webpack/index.js +0 -15
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9821a3370ca6a9a1fa582ab4412d5adea5bbfc125b4102c3bc2a2c92724aaf48
|
4
|
+
data.tar.gz: 6464d913e62d09c6e7318d887f4680a5f7a996a7f537e015a07abd366bda01c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 66f0fe8d87d3b70fd5f23d2892abbe6f7b525e27635bc480eaf6517ae33a3510b81a1f2732373cac7b66f54333e5731f0a457a5d63bda16f233d2615a07efbb0
|
7
|
+
data.tar.gz: 6390c063f681c358200e91b6702bcc235ff953428052ab8b39f13821e26d14b30409ad87df431af468eaf57e6a39437438422016fd817da41ccb1dfaa607b090
|
@@ -37,6 +37,8 @@ module JobInvocationsChartHelper
|
|
37
37
|
_('running %{percent}%%') % {:percent => percent}
|
38
38
|
when HostStatus::ExecutionStatus::OK
|
39
39
|
_('succeeded')
|
40
|
+
when HostStatus::ExecutionStatus::CANCELLED
|
41
|
+
_('cancelled')
|
40
42
|
when HostStatus::ExecutionStatus::ERROR
|
41
43
|
_('failed')
|
42
44
|
else
|
@@ -13,9 +13,13 @@ module RemoteExecutionHelper
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
def template_invocation_status(task)
|
16
|
+
def template_invocation_status(task, parent_task)
|
17
17
|
if task.nil?
|
18
|
-
|
18
|
+
if parent_task.result == 'cancelled'
|
19
|
+
icon_text('warning-triangle-o', _('cancelled'), :kind => 'pficon')
|
20
|
+
else
|
21
|
+
icon_text('question', 'N/A', :kind => 'fa')
|
22
|
+
end
|
19
23
|
elsif task.state == 'running'
|
20
24
|
icon_text('running', _('running'), :kind => 'pficon')
|
21
25
|
elsif task.state == 'planned'
|
@@ -10,5 +10,11 @@ module ::ProxyAPI
|
|
10
10
|
rescue => e
|
11
11
|
raise ProxyException.new(url, e, N_('Unable to fetch public key'))
|
12
12
|
end
|
13
|
+
|
14
|
+
def drop_from_known_hosts(hostname)
|
15
|
+
delete('known_hosts/' + hostname)
|
16
|
+
rescue => e
|
17
|
+
raise ProxyException.new(url, e, N_('Unable to remove host from known hosts'))
|
18
|
+
end
|
13
19
|
end
|
14
20
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module ForemanRemoteExecution
|
2
|
+
module Orchestration::SSH
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
before_destroy :ssh_destroy
|
7
|
+
after_validation :queue_ssh_destroy
|
8
|
+
register_rebuild(:queue_ssh_destroy, N_("SSH_#{self.to_s.split('::').first}"))
|
9
|
+
end
|
10
|
+
|
11
|
+
def drop_from_known_hosts(args)
|
12
|
+
proxy_id, target = args
|
13
|
+
proxy = ::SmartProxy.find(proxy_id)
|
14
|
+
begin
|
15
|
+
proxy.drop_host_from_known_hosts(target)
|
16
|
+
rescue => e
|
17
|
+
Rails.logger.warn e.message
|
18
|
+
return false
|
19
|
+
end
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def ssh_destroy
|
24
|
+
logger.debug "Scheduling SSH known_hosts cleanup"
|
25
|
+
|
26
|
+
host, _kind, target = host_kind_target
|
27
|
+
proxies = host.remote_execution_proxies('SSH').values
|
28
|
+
proxies.flatten.uniq.each do |proxy|
|
29
|
+
queue.create(id: queue_id(proxy.id), name: _("Remove SSH known hosts for %s") % self,
|
30
|
+
priority: 200, action: [self, :drop_from_known_hosts, [proxy.id, target]])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def queue_ssh_destroy
|
35
|
+
should_drop_from_known_hosts? && ssh_destroy
|
36
|
+
end
|
37
|
+
|
38
|
+
def should_drop_from_known_hosts?
|
39
|
+
host, = host_kind_target
|
40
|
+
host&.build && host&.changes&.key?('build')
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def host_kind_target
|
46
|
+
if self.is_a?(::Host::Base)
|
47
|
+
[self, 'host', name]
|
48
|
+
else
|
49
|
+
[self.host, 'interface', ip]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def queue_id(proxy_id)
|
54
|
+
_, kind, id = host_kind_target
|
55
|
+
"ssh_remove_known_hosts_#{kind}_#{id}_#{proxy_id}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -7,8 +7,10 @@ class HostStatus::ExecutionStatus < HostStatus::Status
|
|
7
7
|
QUEUED = 2
|
8
8
|
# execution is in progress, dynflow task was created
|
9
9
|
RUNNING = 3
|
10
|
+
# execution has been cancelled
|
11
|
+
CANCELLED = 4
|
10
12
|
# mapping to string representation
|
11
|
-
STATUS_NAMES = { OK => 'succeeded', ERROR => 'failed', QUEUED => 'queued', RUNNING => 'running' }.freeze
|
13
|
+
STATUS_NAMES = { OK => 'succeeded', ERROR => 'failed', QUEUED => 'queued', RUNNING => 'running', CANCELLED => 'cancelled' }.freeze
|
12
14
|
|
13
15
|
def relevant?(*args)
|
14
16
|
execution_tasks.present?
|
@@ -38,6 +40,8 @@ class HostStatus::ExecutionStatus < HostStatus::Status
|
|
38
40
|
case to_status(options)
|
39
41
|
when OK
|
40
42
|
execution_tasks.present? ? N_('Last execution succeeded') : N_('No execution finished yet')
|
43
|
+
when CANCELLED
|
44
|
+
N_('Last execution cancelled')
|
41
45
|
when ERROR
|
42
46
|
N_('Last execution failed')
|
43
47
|
else
|
@@ -54,6 +58,8 @@ class HostStatus::ExecutionStatus < HostStatus::Status
|
|
54
58
|
case status
|
55
59
|
when OK
|
56
60
|
[ "state = 'stopped' AND result = 'success'" ]
|
61
|
+
when CANCELLED
|
62
|
+
[ "state = 'stopped' AND result = 'cancelled'" ]
|
57
63
|
when ERROR
|
58
64
|
[ "state = 'stopped' AND (result = 'error' OR result = 'warning')" ]
|
59
65
|
when QUEUED
|
@@ -74,6 +80,8 @@ class HostStatus::ExecutionStatus < HostStatus::Status
|
|
74
80
|
QUEUED
|
75
81
|
elsif task.state == 'stopped' && task.result == 'success'
|
76
82
|
OK
|
83
|
+
elsif task.state == 'stopped' && task.result == 'cancelled'
|
84
|
+
CANCELLED
|
77
85
|
elsif task.pending?
|
78
86
|
RUNNING
|
79
87
|
else
|
@@ -1 +1 @@
|
|
1
|
-
<td class="host_status" id="<%= dom_id(host) %>-status" data-refresh_required="<%= task.nil? || task.pending? ? 'true' : '' %>" data-id="<%= host.id %>"><%= template_invocation_status(task) %></td>
|
1
|
+
<td class="host_status" id="<%= dom_id(host) %>-status" data-refresh_required="<%= task.nil? || task.pending? ? 'true' : '' %>" data-id="<%= host.id %>"><%= template_invocation_status(task, job_invocation.task) %></td>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% template_invocations = job_invocation.pattern_template_invocations %>
|
2
2
|
<div class='row'>
|
3
3
|
<div class="col-xs-6 col-sm-6 col-md-6">
|
4
|
-
<%= render :partial => 'card_results' %>
|
4
|
+
<%= render :partial => 'card_results', :locals => { :job_invocation => job_invocation } %>
|
5
5
|
<%= render :partial => 'card_schedule', :locals => { :job_invocation => job_invocation } %>
|
6
6
|
</div>
|
7
7
|
<div class='col-xs-12 col-sm-6 col-md-6'>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% title @job_invocation.description %>
|
2
2
|
<% stylesheet 'foreman_remote_execution/foreman_remote_execution' %>
|
3
3
|
<% javascript 'charts', 'foreman_remote_execution/template_invocation' %>
|
4
|
-
|
4
|
+
<% javascript *webpack_asset_paths('foreman_remote_execution', :extension => 'js') %>
|
5
5
|
|
6
6
|
<%= breadcrumbs name_field: 'description' %>
|
7
7
|
|
data/config/routes.rb
CHANGED
@@ -16,7 +16,8 @@ Rails.application.routes.draw do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
match 'job_invocations/new', to: 'job_invocations#new', via: [:get, :post], as: 'new_job_invocation'
|
20
|
+
resources :job_invocations, :only => [:create, :show, :index] do
|
20
21
|
collection do
|
21
22
|
post 'refresh'
|
22
23
|
get 'chart'
|
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.extra_rdoc_files = Dir['README*', 'LICENSE']
|
26
26
|
|
27
27
|
s.add_dependency 'deface'
|
28
|
-
s.add_dependency 'dynflow', '>= 1.0.
|
28
|
+
s.add_dependency 'dynflow', '>= 1.0.2', '< 2.0.0'
|
29
29
|
s.add_dependency 'foreman_remote_execution_core'
|
30
30
|
s.add_dependency 'foreman-tasks', '>= 0.15.1'
|
31
31
|
|
@@ -166,10 +166,12 @@ module ForemanRemoteExecution
|
|
166
166
|
|
167
167
|
Host::Managed.prepend ForemanRemoteExecution::HostExtensions
|
168
168
|
Host::Managed.include ForemanTasks::Concerns::HostActionSubject
|
169
|
+
Host::Managed.include ForemanRemoteExecution::Orchestration::SSH
|
169
170
|
|
170
171
|
(Nic::Base.descendants + [Nic::Base]).each do |klass|
|
171
172
|
klass.send(:include, ForemanRemoteExecution::NicExtensions)
|
172
173
|
end
|
174
|
+
Nic::Managed.include ForemanRemoteExecution::Orchestration::SSH
|
173
175
|
|
174
176
|
Bookmark.include ForemanRemoteExecution::BookmarkExtensions
|
175
177
|
HostsHelper.prepend ForemanRemoteExecution::HostsHelperExtensions
|
@@ -46,4 +46,16 @@ class JobInvocationsControllerTest < ActionController::TestCase
|
|
46
46
|
assert_equal(template_invocation_params,
|
47
47
|
assigns(:composer).params['template_invocations'])
|
48
48
|
end
|
49
|
+
|
50
|
+
test 'new via GET and POST' do
|
51
|
+
template = FactoryBot.create(:job_template, :with_input)
|
52
|
+
feature = FactoryBot.create(:remote_execution_feature, job_template: template)
|
53
|
+
params = { feature: feature.label, inputs: { template.template_inputs.first.name => 'foobar' } }
|
54
|
+
|
55
|
+
get :new, params: params, session: set_session_user
|
56
|
+
assert_response :success
|
57
|
+
|
58
|
+
post :new, params: params, session: set_session_user
|
59
|
+
assert_response :success
|
60
|
+
end
|
49
61
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'test_plugin_helper'
|
2
|
+
|
3
|
+
class SSHOrchestrationTest < ActiveSupport::TestCase
|
4
|
+
let(:host) { FactoryBot.create(:host, :managed, :with_subnet) }
|
5
|
+
let(:proxy) { FactoryBot.create(:smart_proxy, :ssh) }
|
6
|
+
let(:interface) { host.interfaces.first }
|
7
|
+
|
8
|
+
before { interface.subnet.remote_execution_proxies = [proxy] }
|
9
|
+
|
10
|
+
it 'attempts to drop IP address and hostname from smart proxies on destroy' do
|
11
|
+
host.stubs(:skip_orchestration?).returns false
|
12
|
+
SmartProxy.any_instance.expects(:drop_host_from_known_hosts).with(interface.ip)
|
13
|
+
SmartProxy.any_instance.expects(:drop_host_from_known_hosts).with(host.name)
|
14
|
+
host.destroy
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'attempts to drop IP address and hostname from smart proxies on rebuild' do
|
18
|
+
host.build = true
|
19
|
+
host.save!
|
20
|
+
ids = ["ssh_remove_known_hosts_interface_#{interface.ip}_#{proxy.id}",
|
21
|
+
"ssh_remove_known_hosts_host_#{host.name}_#{proxy.id}"]
|
22
|
+
_(host.queue.task_ids).must_equal ids
|
23
|
+
end
|
24
|
+
end
|
@@ -149,7 +149,10 @@ class RemoteExecutionProviderTest < ActiveSupport::TestCase
|
|
149
149
|
FactoryBot.create(:host) do |host|
|
150
150
|
host.interfaces = [FactoryBot.build(:nic_managed, flags.merge(:ip => nil, :name => 'somehost.somedomain.org', :primary => true)),
|
151
151
|
FactoryBot.build(:nic_managed, flags.merge(:ip => '127.0.0.1'))]
|
152
|
-
end
|
152
|
+
end.reload
|
153
|
+
# Reassigning the interfaces triggers the on-deletion ssh key removal for the interface which is being replaced
|
154
|
+
# This has an undesired side effect of caching the original interface as execution one which made the tests
|
155
|
+
# give wrong results. Reloading the host wipes the cache
|
153
156
|
end
|
154
157
|
|
155
158
|
let(:flags) do
|
data/webpack/index.js
CHANGED
@@ -12,18 +12,3 @@ componentRegistry.register({
|
|
12
12
|
});
|
13
13
|
|
14
14
|
registerReducer('foremanRemoteExecutionReducers', rootReducer);
|
15
|
-
|
16
|
-
if (window.location.href.match(/job_invocations/)) {
|
17
|
-
const jobInvocationId = parseInt(
|
18
|
-
new URI(window.location.href).filename(),
|
19
|
-
10,
|
20
|
-
);
|
21
|
-
|
22
|
-
const mountJobInvocationContainer = () => {
|
23
|
-
mount('JobInvocationContainer', '#status_chart', {
|
24
|
-
url: `/job_invocations/chart?id=${jobInvocationId}`,
|
25
|
-
});
|
26
|
-
};
|
27
|
-
|
28
|
-
document.addEventListener('page:change', mountJobInvocationContainer);
|
29
|
-
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_remote_execution
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Foreman Remote Execution team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deface
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.0.
|
33
|
+
version: 1.0.2
|
34
34
|
- - "<"
|
35
35
|
- !ruby/object:Gem::Version
|
36
36
|
version: 2.0.0
|
@@ -40,7 +40,7 @@ dependencies:
|
|
40
40
|
requirements:
|
41
41
|
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 1.0.
|
43
|
+
version: 1.0.2
|
44
44
|
- - "<"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 2.0.0
|
@@ -178,6 +178,7 @@ files:
|
|
178
178
|
- app/models/concerns/foreman_remote_execution/foreman_tasks_triggering_extensions.rb
|
179
179
|
- app/models/concerns/foreman_remote_execution/host_extensions.rb
|
180
180
|
- app/models/concerns/foreman_remote_execution/nic_extensions.rb
|
181
|
+
- app/models/concerns/foreman_remote_execution/orchestration/ssh.rb
|
181
182
|
- app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb
|
182
183
|
- app/models/concerns/foreman_remote_execution/subnet_extensions.rb
|
183
184
|
- app/models/concerns/foreman_remote_execution/taxonomy_extensions.rb
|
@@ -377,6 +378,7 @@ files:
|
|
377
378
|
- test/functional/job_invocations_controller_test.rb
|
378
379
|
- test/functional/job_templates_controller_test.rb
|
379
380
|
- test/helpers/remote_execution_helper_test.rb
|
381
|
+
- test/models/orchestration/ssh_test.rb
|
380
382
|
- test/test_plugin_helper.rb
|
381
383
|
- test/unit/actions/run_host_job_test.rb
|
382
384
|
- test/unit/actions/run_hosts_job_test.rb
|
@@ -442,6 +444,7 @@ test_files:
|
|
442
444
|
- test/functional/job_invocations_controller_test.rb
|
443
445
|
- test/functional/job_templates_controller_test.rb
|
444
446
|
- test/helpers/remote_execution_helper_test.rb
|
447
|
+
- test/models/orchestration/ssh_test.rb
|
445
448
|
- test/test_plugin_helper.rb
|
446
449
|
- test/unit/actions/run_host_job_test.rb
|
447
450
|
- test/unit/actions/run_hosts_job_test.rb
|