foreman_remote_execution 3.2.1 → 3.3.3
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/.eslintrc +5 -30
- data/.github/workflows/ci.yml +101 -0
- data/.gitignore +1 -0
- data/.rubocop_todo.yml +3 -0
- data/Gemfile +1 -0
- data/app/assets/stylesheets/foreman_remote_execution/job_invocations.scss +6 -5
- data/app/controllers/api/v2/job_invocations_controller.rb +22 -1
- data/app/controllers/api/v2/template_invocations_controller.rb +4 -1
- data/app/helpers/job_invocations_helper.rb +1 -1
- data/app/helpers/remote_execution_helper.rb +38 -33
- data/app/lib/actions/remote_execution/run_host_job.rb +3 -2
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +1 -1
- data/app/models/concerns/foreman_remote_execution/orchestration/ssh.rb +10 -5
- data/app/models/remote_execution_provider.rb +5 -0
- data/app/services/default_proxy_proxy_selector.rb +18 -0
- data/app/views/api/v2/job_invocations/main.json.rabl +8 -2
- data/app/views/job_invocations/_card_target_hosts.html.erb +1 -1
- data/app/views/job_invocations/_tab_hosts.html.erb +3 -23
- data/app/views/job_invocations/index.html.erb +2 -1
- data/app/views/job_invocations/show.html.erb +0 -6
- data/app/views/job_invocations/show.json.erb +4 -0
- data/app/views/templates/ssh/package_action.erb +1 -0
- data/app/views/templates/ssh/puppet_agent_disable.erb +3 -0
- data/app/views/templates/ssh/puppet_agent_enable.erb +3 -0
- data/app/views/templates/ssh/puppet_install_modules_from_forge.erb +3 -0
- data/app/views/templates/ssh/puppet_run_once.erb +3 -0
- data/db/seeds.d/70-job_templates.rb +1 -1
- data/foreman_remote_execution.gemspec +4 -5
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/locale/action_names.rb +0 -1
- data/package.json +16 -33
- data/test/functional/api/v2/job_invocations_controller_test.rb +42 -14
- data/test/models/orchestration/ssh_test.rb +32 -0
- data/test/unit/concerns/host_extensions_test.rb +7 -0
- data/webpack/__mocks__/foremanReact/common/I18n.js +1 -0
- data/webpack/__mocks__/foremanReact/components/common/ActionButtons/ActionButtons.js +3 -0
- data/webpack/__mocks__/foremanReact/constants.js +3 -0
- data/webpack/index.js +9 -7
- data/webpack/react_app/components/TargetingHosts/TargetingHosts.js +52 -0
- data/webpack/react_app/components/TargetingHosts/TargetingHostsActions.js +8 -0
- data/webpack/react_app/components/TargetingHosts/TargetingHostsConsts.js +1 -0
- data/webpack/react_app/components/TargetingHosts/TargetingHostsSelectors.js +12 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/HostItem.test.js +6 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/HostStatus.test.js +6 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/TargetingHosts.test.js +6 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/HostItem.test.js.snap +31 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/HostStatus.test.js.snap +12 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHosts.test.js.snap +81 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/fixtures.js +43 -0
- data/webpack/react_app/components/TargetingHosts/components/HostItem.js +39 -0
- data/webpack/react_app/components/TargetingHosts/components/HostStatus.js +54 -0
- data/webpack/react_app/components/TargetingHosts/index.js +37 -0
- data/webpack/react_app/components/jobInvocations/AggregateStatus/index.js +10 -0
- data/webpack/react_app/components/jobInvocations/AggregateStatus/index.test.js +6 -3
- data/webpack/react_app/components/jobInvocations/index.js +19 -7
- data/webpack/react_app/redux/actions/jobInvocations/index.js +12 -8
- data/webpack/react_app/redux/consts.js +1 -2
- data/webpack/react_app/redux/reducers/jobInvocations/index.fixtures.js +8 -40
- data/webpack/react_app/redux/reducers/jobInvocations/index.test.js +17 -11
- data/webpack/test_setup.js +2 -1
- metadata +26 -12
- data/.hound.yml +0 -19
- data/.travis.yml +0 -6
- data/app/views/job_invocations/_host_actions_td.html.erb +0 -3
- data/app/views/job_invocations/_host_name_td.html.erb +0 -8
- data/app/views/job_invocations/_host_status_td.html.erb +0 -1
- data/app/views/job_invocations/show.js.erb +0 -23
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9caa7b15e9d581680796ce9780382a7b81a62366923aa97949b5dc4c8615696a
|
|
4
|
+
data.tar.gz: 9c27c825131b46779740cceb8aa78f8dcad774ead3b22068b41ff07586387dbf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6712bf834fa6adffa3289fdcc77cce424d035460c5dc6c7a2259c894c3b957e55624190ef86fe94786347c685c0d5249eebdc9ff3d38b4cf2721d1bcefa65fd4
|
|
7
|
+
data.tar.gz: 144182693223e9379d60ba6415506e1ccd30633da0a9303ae4e89565166c7ae0e300c72e17681c3092d495fc6b496b87ffa1e700c3041d4369077ecca2faa236
|
data/.eslintrc
CHANGED
|
@@ -1,32 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"extends": [
|
|
4
|
-
|
|
5
|
-
"
|
|
6
|
-
]
|
|
7
|
-
"env": {
|
|
8
|
-
"browser": true,
|
|
9
|
-
"es6": true,
|
|
10
|
-
"node": true,
|
|
11
|
-
"jasmine": true,
|
|
12
|
-
"jest": true
|
|
13
|
-
},
|
|
14
|
-
"parser": "babel-eslint",
|
|
15
|
-
"rules": {
|
|
16
|
-
"react/jsx-uses-vars": "error",
|
|
17
|
-
"react/jsx-uses-react": "error",
|
|
18
|
-
"no-unused-vars": [
|
|
19
|
-
"error",
|
|
20
|
-
{
|
|
21
|
-
"vars": "all",
|
|
22
|
-
"args": "none"
|
|
23
|
-
}
|
|
24
|
-
],
|
|
25
|
-
"no-underscore-dangle": "off",
|
|
26
|
-
"no-use-before-define": "off",
|
|
27
|
-
"import/prefer-default-export": "off",
|
|
28
|
-
// Import rules off for now due to HoundCI issue
|
|
29
|
-
"import/no-unresolved": "off",
|
|
30
|
-
"import/extensions": "off"
|
|
31
|
-
}
|
|
2
|
+
"plugins": ["@theforeman/foreman"],
|
|
3
|
+
"extends": [
|
|
4
|
+
"plugin:@theforeman/foreman/core",
|
|
5
|
+
"plugin:@theforeman/foreman/plugins"
|
|
6
|
+
]
|
|
32
7
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on: [pull_request]
|
|
3
|
+
env:
|
|
4
|
+
RAILS_ENV: test
|
|
5
|
+
DATABASE_URL: postgresql://postgres:@localhost/test
|
|
6
|
+
DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL: true
|
|
7
|
+
jobs:
|
|
8
|
+
rubocop:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v2
|
|
12
|
+
- name: Setup Ruby
|
|
13
|
+
uses: ruby/setup-ruby@v1
|
|
14
|
+
with:
|
|
15
|
+
ruby-version: 2.6
|
|
16
|
+
- name: Setup
|
|
17
|
+
run: |
|
|
18
|
+
gem install bundler
|
|
19
|
+
bundle install --jobs=3 --retry=3
|
|
20
|
+
- name: Run rubocop
|
|
21
|
+
run: bundle exec rubocop
|
|
22
|
+
test_ruby:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
needs: rubocop
|
|
25
|
+
services:
|
|
26
|
+
postgres:
|
|
27
|
+
image: postgres:12.1
|
|
28
|
+
ports: ['5432:5432']
|
|
29
|
+
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
|
30
|
+
strategy:
|
|
31
|
+
fail-fast: false
|
|
32
|
+
matrix:
|
|
33
|
+
foreman-core-branch: [2.1-stable, develop]
|
|
34
|
+
ruby-version: [2.5, 2.6]
|
|
35
|
+
node-version: [12]
|
|
36
|
+
steps:
|
|
37
|
+
- run: sudo apt-get update
|
|
38
|
+
- run: sudo apt-get install build-essential libcurl4-openssl-dev zlib1g-dev libpq-dev
|
|
39
|
+
- uses: actions/checkout@v2
|
|
40
|
+
with:
|
|
41
|
+
repository: theforeman/foreman
|
|
42
|
+
ref: ${{ matrix.foreman-core-branch }}
|
|
43
|
+
- uses: actions/checkout@v2
|
|
44
|
+
with:
|
|
45
|
+
path: foreman_remote_execution
|
|
46
|
+
- name: Setup Ruby
|
|
47
|
+
uses: ruby/setup-ruby@v1
|
|
48
|
+
with:
|
|
49
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
50
|
+
- name: Setup Node
|
|
51
|
+
uses: actions/setup-node@v1
|
|
52
|
+
with:
|
|
53
|
+
node-version: ${{ matrix.node-version }}
|
|
54
|
+
- uses: actions/cache@v1
|
|
55
|
+
with:
|
|
56
|
+
path: vendor/bundle
|
|
57
|
+
key: ${{ runner.os }}-fgems-${{ matrix.ruby-version }}-${{ hashFiles('Gemfile.lock') }}
|
|
58
|
+
restore-keys: |
|
|
59
|
+
${{ runner.os }}-fgems-${{ matrix.ruby-version }}-
|
|
60
|
+
- name: Setup Bundler
|
|
61
|
+
run: |
|
|
62
|
+
echo "gem 'foreman_remote_execution', path: './foreman_remote_execution'" > bundler.d/foreman_remote_execution.local.rb
|
|
63
|
+
gem install bundler
|
|
64
|
+
bundle config set without journald development console libvirt
|
|
65
|
+
bundle config set path vendor/bundle
|
|
66
|
+
- name: Prepare test env
|
|
67
|
+
run: |
|
|
68
|
+
bundle install --jobs=3 --retry=3
|
|
69
|
+
bundle exec rake db:create
|
|
70
|
+
bundle exec rake db:migrate
|
|
71
|
+
- name: Run plugin tests
|
|
72
|
+
run: |
|
|
73
|
+
bundle exec rake test:foreman_remote_execution
|
|
74
|
+
bundle exec rake test TEST="test/unit/foreman/access_permissions_test.rb"
|
|
75
|
+
test_js:
|
|
76
|
+
runs-on: ubuntu-latest
|
|
77
|
+
needs: rubocop
|
|
78
|
+
strategy:
|
|
79
|
+
fail-fast: false
|
|
80
|
+
matrix:
|
|
81
|
+
ruby-version: [2.6]
|
|
82
|
+
node-version: [10, 12]
|
|
83
|
+
steps:
|
|
84
|
+
- uses: actions/checkout@v2
|
|
85
|
+
- name: Setup Ruby
|
|
86
|
+
uses: ruby/setup-ruby@v1
|
|
87
|
+
with:
|
|
88
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
89
|
+
- name: Setup Node
|
|
90
|
+
uses: actions/setup-node@v1
|
|
91
|
+
with:
|
|
92
|
+
node-version: ${{ matrix.node-version }}
|
|
93
|
+
- name: Nmp install
|
|
94
|
+
run: |
|
|
95
|
+
npm install
|
|
96
|
+
- name: Run plugin linter
|
|
97
|
+
run: |
|
|
98
|
+
npm run lint
|
|
99
|
+
- name: Run plugin tests
|
|
100
|
+
run: |
|
|
101
|
+
npm run test
|
data/.gitignore
CHANGED
data/.rubocop_todo.yml
CHANGED
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
+
Minitest/GlobalExpectations:
|
|
10
|
+
Enabled: false
|
|
11
|
+
|
|
9
12
|
# Offense count: 2
|
|
10
13
|
# Cop supports --auto-correct.
|
|
11
14
|
# Configuration parameters: TreatCommentsAsGroupSeparators, Include.
|
data/Gemfile
CHANGED
|
@@ -18,7 +18,17 @@ module Api
|
|
|
18
18
|
|
|
19
19
|
api :GET, '/job_invocations/:id', N_('Show job invocation')
|
|
20
20
|
param :id, :identifier, :required => true
|
|
21
|
+
param :host_status, :bool, required: false, desc: N_('Show Job status for the hosts')
|
|
21
22
|
def show
|
|
23
|
+
@hosts = @job_invocation.targeting.hosts.authorized(:view_hosts, Host)
|
|
24
|
+
@template_invocations = @job_invocation.template_invocations
|
|
25
|
+
.where(host: @hosts)
|
|
26
|
+
.includes(:input_values)
|
|
27
|
+
|
|
28
|
+
if params[:host_status] == 'true'
|
|
29
|
+
template_invocations = @template_invocations.includes(:run_host_job_task).to_a
|
|
30
|
+
@host_statuses = Hash[template_invocations.map { |ti| [ti.host_id, template_invocation_status(ti)] }]
|
|
31
|
+
end
|
|
22
32
|
end
|
|
23
33
|
|
|
24
34
|
def_param_group :job_invocation do
|
|
@@ -146,7 +156,7 @@ module Api
|
|
|
146
156
|
end
|
|
147
157
|
|
|
148
158
|
def find_host
|
|
149
|
-
@host =
|
|
159
|
+
@host = @nested_obj.targeting.hosts.authorized(:view_hosts, Host).find(params['host_id'])
|
|
150
160
|
rescue ActiveRecord::RecordNotFound
|
|
151
161
|
not_found({ :error => { :message => (_("Host with id '%{id}' was not found") % { :id => params['host_id'] }) } })
|
|
152
162
|
end
|
|
@@ -204,6 +214,17 @@ module Api
|
|
|
204
214
|
def parent_scope
|
|
205
215
|
resource_class.where(nil)
|
|
206
216
|
end
|
|
217
|
+
|
|
218
|
+
def template_invocation_status(template_invocation)
|
|
219
|
+
task = template_invocation.try(:run_host_job_task)
|
|
220
|
+
parent_task = @job_invocation.task
|
|
221
|
+
|
|
222
|
+
return(parent_task.result == 'cancelled' ? 'cancelled' : 'N/A') if task.nil?
|
|
223
|
+
return task.state if task.state == 'running' || task.state == 'planned'
|
|
224
|
+
return 'error' if task.result == 'warning'
|
|
225
|
+
|
|
226
|
+
task.result
|
|
227
|
+
end
|
|
207
228
|
end
|
|
208
229
|
end
|
|
209
230
|
end
|
|
@@ -26,7 +26,10 @@ module Api
|
|
|
26
26
|
private
|
|
27
27
|
|
|
28
28
|
def resource_scope_for_template_invocations
|
|
29
|
-
@job_invocation.template_invocations
|
|
29
|
+
@job_invocation.template_invocations
|
|
30
|
+
.includes(:host)
|
|
31
|
+
.where(host: Host.authorized(:view_hosts, Host))
|
|
32
|
+
.search_for(*search_options)
|
|
30
33
|
end
|
|
31
34
|
|
|
32
35
|
def find_job_invocation
|
|
@@ -29,7 +29,7 @@ module JobInvocationsHelper
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def preview_hosts(template_invocation)
|
|
32
|
-
hosts = template_invocation.targeting.hosts.take(20)
|
|
32
|
+
hosts = template_invocation.targeting.hosts.authorized(:view_hosts, Host).take(20)
|
|
33
33
|
hosts.map do |host|
|
|
34
34
|
collapsed_preview(host) +
|
|
35
35
|
render(:partial => 'job_invocations/user_input',
|
|
@@ -14,43 +14,35 @@ module RemoteExecutionHelper
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def template_invocation_status(task, parent_task)
|
|
17
|
-
if task.nil?
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
end
|
|
23
|
-
elsif task.state == 'running'
|
|
24
|
-
icon_text('running', _('running'), :kind => 'pficon')
|
|
25
|
-
elsif task.state == 'planned'
|
|
26
|
-
icon_text('build', _('planned'), :kind => 'pficon')
|
|
27
|
-
else
|
|
28
|
-
case task.result
|
|
29
|
-
when 'warning', 'error'
|
|
30
|
-
icon_text('error-circle-o', _('failed'), :kind => 'pficon')
|
|
31
|
-
when 'cancelled'
|
|
32
|
-
icon_text('warning-triangle-o', _('cancelled'), :kind => 'pficon')
|
|
33
|
-
when 'success'
|
|
34
|
-
icon_text('ok', _('success'), :kind => 'pficon')
|
|
35
|
-
else
|
|
36
|
-
task.result
|
|
37
|
-
end
|
|
38
|
-
end
|
|
17
|
+
return(parent_task.result == 'cancelled' ? _('cancelled') : 'N/A') if task.nil?
|
|
18
|
+
return task.state if task.state == 'running' || task.state == 'planned'
|
|
19
|
+
return _('error') if task.result == 'warning'
|
|
20
|
+
|
|
21
|
+
task.result
|
|
39
22
|
end
|
|
40
23
|
|
|
41
24
|
def template_invocation_actions(task, host, job_invocation, template_invocation)
|
|
25
|
+
links = []
|
|
42
26
|
host_task = template_invocation.try(:run_host_job_task)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
27
|
+
|
|
28
|
+
if authorized_for(hash_for_host_path(host).merge(auth_object: host, permission: :view_hosts, authorizer: job_hosts_authorizer))
|
|
29
|
+
links << { title: _('Host detail'),
|
|
30
|
+
action: { href: host_path(host), 'data-method': 'get', id: "#{host.name}-actions-detail" } }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if authorized_for(hash_for_rerun_job_invocation_path(id: job_invocation, host_ids: [ host.id ], authorizer: job_hosts_authorizer))
|
|
34
|
+
links << { title: (_('Rerun on %s') % host.name),
|
|
35
|
+
action: { href: rerun_job_invocation_path(job_invocation, host_ids: [ host.id ]),
|
|
36
|
+
'data-method': 'get', id: "#{host.name}-actions-rerun" } }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
if host_task.present? && authorized_for(hash_for_foreman_tasks_task_path(host_task).merge(auth_object: host_task, permission: :view_foreman_tasks))
|
|
40
|
+
links << { title: _('Host task'),
|
|
41
|
+
action: { href: foreman_tasks_task_path(host_task),
|
|
42
|
+
'data-method': 'get', id: "#{host.name}-actions-task" } }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
links
|
|
54
46
|
end
|
|
55
47
|
|
|
56
48
|
def remote_execution_provider_for(template_invocation)
|
|
@@ -237,4 +229,17 @@ module RemoteExecutionHelper
|
|
|
237
229
|
|
|
238
230
|
task.execution_plan.actions[1].try(:input).try(:[], 'script')
|
|
239
231
|
end
|
|
232
|
+
|
|
233
|
+
def targeting_hosts(job_invocation, hosts)
|
|
234
|
+
hosts.map do |host|
|
|
235
|
+
template_invocation = job_invocation.template_invocations.find { |template_inv| template_inv.host_id == host.id }
|
|
236
|
+
task = template_invocation.try(:run_host_job_task)
|
|
237
|
+
link_authorized = !task.nil? && authorized_for(hash_for_template_invocation_path(:id => template_invocation).merge(:auth_object => host, :permission => :view_hosts, :authorizer => job_hosts_authorizer))
|
|
238
|
+
|
|
239
|
+
{ name: host.name,
|
|
240
|
+
link: link_authorized ? template_invocation_path(:id => template_invocation) : '',
|
|
241
|
+
status: template_invocation_status(task, job_invocation.task),
|
|
242
|
+
actions: template_invocation_actions(task, host, job_invocation, template_invocation) }
|
|
243
|
+
end
|
|
244
|
+
end
|
|
240
245
|
end
|
|
@@ -29,6 +29,9 @@ module Actions
|
|
|
29
29
|
|
|
30
30
|
raise _('Could not use any template used in the job invocation') if template_invocation.blank?
|
|
31
31
|
|
|
32
|
+
provider = template_invocation.template.provider
|
|
33
|
+
proxy_selector = provider.required_proxy_selector_for(template_invocation.template) || proxy_selector
|
|
34
|
+
|
|
32
35
|
provider_type = template_invocation.template.provider_type.to_s
|
|
33
36
|
proxy = determine_proxy!(proxy_selector, provider_type, host)
|
|
34
37
|
|
|
@@ -36,8 +39,6 @@ module Actions
|
|
|
36
39
|
script = renderer.render
|
|
37
40
|
raise _('Failed rendering template: %s') % renderer.error_message unless script
|
|
38
41
|
|
|
39
|
-
provider = template_invocation.template.provider
|
|
40
|
-
|
|
41
42
|
additional_options = { :hostname => provider.find_ip_or_hostname(host),
|
|
42
43
|
:script => script,
|
|
43
44
|
:execution_timeout_interval => job_invocation.execution_timeout_interval,
|
|
@@ -49,7 +49,7 @@ module ForemanRemoteExecution
|
|
|
49
49
|
keys = remote_execution_ssh_keys
|
|
50
50
|
source = 'global'
|
|
51
51
|
if keys.present?
|
|
52
|
-
value, safe_value = params.fetch('remote_execution_ssh_keys', {}).values_at(:value, :safe_value).map { |v| v
|
|
52
|
+
value, safe_value = params.fetch('remote_execution_ssh_keys', {}).values_at(:value, :safe_value).map { |v| [v].flatten.compact }
|
|
53
53
|
params['remote_execution_ssh_keys'] = {:value => value + keys, :safe_value => safe_value + keys, :source => source}
|
|
54
54
|
end
|
|
55
55
|
[:remote_execution_ssh_user, :remote_execution_effective_user_method,
|
|
@@ -8,11 +8,16 @@ module ForemanRemoteExecution
|
|
|
8
8
|
register_rebuild(:queue_ssh_destroy, N_("SSH_#{self.to_s.split('::').first}"))
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def drop_from_known_hosts(
|
|
12
|
-
|
|
11
|
+
def drop_from_known_hosts(proxy_id)
|
|
12
|
+
_, _, target = host_kind_target
|
|
13
|
+
return true if target.nil?
|
|
14
|
+
|
|
13
15
|
proxy = ::SmartProxy.find(proxy_id)
|
|
14
16
|
begin
|
|
15
17
|
proxy.drop_host_from_known_hosts(target)
|
|
18
|
+
rescue RestClient::ResourceNotFound => e
|
|
19
|
+
# ignore 404 when known_hosts entry is missing or the module was not enabled
|
|
20
|
+
Foreman::Logging.exception "Proxy failed to delete SSH known_hosts for #{name}, #{ip}", e, :level => :error
|
|
16
21
|
rescue => e
|
|
17
22
|
Rails.logger.warn e.message
|
|
18
23
|
return false
|
|
@@ -23,11 +28,11 @@ module ForemanRemoteExecution
|
|
|
23
28
|
def ssh_destroy
|
|
24
29
|
logger.debug "Scheduling SSH known_hosts cleanup"
|
|
25
30
|
|
|
26
|
-
host, _kind,
|
|
31
|
+
host, _kind, _target = host_kind_target
|
|
27
32
|
proxies = host.remote_execution_proxies('SSH').values
|
|
28
33
|
proxies.flatten.uniq.each do |proxy|
|
|
29
34
|
queue.create(id: queue_id(proxy.id), name: _("Remove SSH known hosts for %s") % self,
|
|
30
|
-
priority: 200, action: [self, :drop_from_known_hosts,
|
|
35
|
+
priority: 200, action: [self, :drop_from_known_hosts, proxy.id])
|
|
31
36
|
end
|
|
32
37
|
end
|
|
33
38
|
|
|
@@ -37,7 +42,7 @@ module ForemanRemoteExecution
|
|
|
37
42
|
|
|
38
43
|
def should_drop_from_known_hosts?
|
|
39
44
|
host, = host_kind_target
|
|
40
|
-
host
|
|
45
|
+
host && !host.new_record? && host.build && host.changes.key?('build')
|
|
41
46
|
end
|
|
42
47
|
|
|
43
48
|
private
|
|
@@ -98,5 +98,10 @@ class RemoteExecutionProvider
|
|
|
98
98
|
def proxy_action_class
|
|
99
99
|
ForemanRemoteExecutionCore::Actions::RunScript
|
|
100
100
|
end
|
|
101
|
+
|
|
102
|
+
# Return a specific proxy selector to use for running a given template
|
|
103
|
+
# Returns either nil to use the default selector or an instance of a (sub)class of ::ForemanTasks::ProxySelector
|
|
104
|
+
def required_proxy_selector_for(_template)
|
|
105
|
+
end
|
|
101
106
|
end
|
|
102
107
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class DefaultProxyProxySelector < ::RemoteExecutionProxySelector
|
|
2
|
+
def initialize
|
|
3
|
+
# TODO: Remove this once we have a reliable way of determining the internal proxy without katello
|
|
4
|
+
# Tracked as https://projects.theforeman.org/issues/29840
|
|
5
|
+
raise _('Internal proxy selector can only be used if Katello is enabled') unless defined?(::Katello)
|
|
6
|
+
|
|
7
|
+
super
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def available_proxies(host, provider)
|
|
11
|
+
# TODO: Once we have a internal proxy marker/feature on the proxy, we can
|
|
12
|
+
# swap the implementation
|
|
13
|
+
internal_proxy = ::Katello.default_capsule
|
|
14
|
+
super.reduce({}) do |acc, (key, proxies)|
|
|
15
|
+
acc.merge(key => proxies.select { |proxy| proxy == internal_proxy })
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|