foreman_remote_execution 3.2.1 → 3.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc +5 -30
  3. data/.github/workflows/ci.yml +101 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop_todo.yml +3 -0
  6. data/Gemfile +1 -0
  7. data/app/assets/stylesheets/foreman_remote_execution/job_invocations.scss +6 -5
  8. data/app/controllers/api/v2/job_invocations_controller.rb +22 -1
  9. data/app/controllers/api/v2/template_invocations_controller.rb +4 -1
  10. data/app/helpers/job_invocations_helper.rb +1 -1
  11. data/app/helpers/remote_execution_helper.rb +38 -33
  12. data/app/lib/actions/remote_execution/run_host_job.rb +3 -2
  13. data/app/models/concerns/foreman_remote_execution/host_extensions.rb +1 -1
  14. data/app/models/concerns/foreman_remote_execution/orchestration/ssh.rb +10 -5
  15. data/app/models/remote_execution_provider.rb +5 -0
  16. data/app/services/default_proxy_proxy_selector.rb +18 -0
  17. data/app/views/api/v2/job_invocations/main.json.rabl +8 -2
  18. data/app/views/job_invocations/_card_target_hosts.html.erb +1 -1
  19. data/app/views/job_invocations/_tab_hosts.html.erb +3 -23
  20. data/app/views/job_invocations/index.html.erb +2 -1
  21. data/app/views/job_invocations/show.html.erb +0 -6
  22. data/app/views/job_invocations/show.json.erb +4 -0
  23. data/app/views/templates/ssh/package_action.erb +1 -0
  24. data/app/views/templates/ssh/puppet_agent_disable.erb +3 -0
  25. data/app/views/templates/ssh/puppet_agent_enable.erb +3 -0
  26. data/app/views/templates/ssh/puppet_install_modules_from_forge.erb +3 -0
  27. data/app/views/templates/ssh/puppet_run_once.erb +3 -0
  28. data/db/seeds.d/70-job_templates.rb +1 -1
  29. data/foreman_remote_execution.gemspec +4 -5
  30. data/lib/foreman_remote_execution/version.rb +1 -1
  31. data/locale/action_names.rb +0 -1
  32. data/package.json +16 -33
  33. data/test/functional/api/v2/job_invocations_controller_test.rb +42 -14
  34. data/test/models/orchestration/ssh_test.rb +32 -0
  35. data/test/unit/concerns/host_extensions_test.rb +7 -0
  36. data/webpack/__mocks__/foremanReact/common/I18n.js +1 -0
  37. data/webpack/__mocks__/foremanReact/components/common/ActionButtons/ActionButtons.js +3 -0
  38. data/webpack/__mocks__/foremanReact/constants.js +3 -0
  39. data/webpack/index.js +9 -7
  40. data/webpack/react_app/components/TargetingHosts/TargetingHosts.js +52 -0
  41. data/webpack/react_app/components/TargetingHosts/TargetingHostsActions.js +8 -0
  42. data/webpack/react_app/components/TargetingHosts/TargetingHostsConsts.js +1 -0
  43. data/webpack/react_app/components/TargetingHosts/TargetingHostsSelectors.js +12 -0
  44. data/webpack/react_app/components/TargetingHosts/__tests__/HostItem.test.js +6 -0
  45. data/webpack/react_app/components/TargetingHosts/__tests__/HostStatus.test.js +6 -0
  46. data/webpack/react_app/components/TargetingHosts/__tests__/TargetingHosts.test.js +6 -0
  47. data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/HostItem.test.js.snap +31 -0
  48. data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/HostStatus.test.js.snap +12 -0
  49. data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHosts.test.js.snap +81 -0
  50. data/webpack/react_app/components/TargetingHosts/__tests__/fixtures.js +43 -0
  51. data/webpack/react_app/components/TargetingHosts/components/HostItem.js +39 -0
  52. data/webpack/react_app/components/TargetingHosts/components/HostStatus.js +54 -0
  53. data/webpack/react_app/components/TargetingHosts/index.js +37 -0
  54. data/webpack/react_app/components/jobInvocations/AggregateStatus/index.js +10 -0
  55. data/webpack/react_app/components/jobInvocations/AggregateStatus/index.test.js +6 -3
  56. data/webpack/react_app/components/jobInvocations/index.js +19 -7
  57. data/webpack/react_app/redux/actions/jobInvocations/index.js +12 -8
  58. data/webpack/react_app/redux/consts.js +1 -2
  59. data/webpack/react_app/redux/reducers/jobInvocations/index.fixtures.js +8 -40
  60. data/webpack/react_app/redux/reducers/jobInvocations/index.test.js +17 -11
  61. data/webpack/test_setup.js +2 -1
  62. metadata +26 -12
  63. data/.hound.yml +0 -19
  64. data/.travis.yml +0 -6
  65. data/app/views/job_invocations/_host_actions_td.html.erb +0 -3
  66. data/app/views/job_invocations/_host_name_td.html.erb +0 -8
  67. data/app/views/job_invocations/_host_status_td.html.erb +0 -1
  68. 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: 9caedc0baf4a767d6b0149fd1b349b97081460193cdccad1cb9a3208d278b67f
4
- data.tar.gz: 709c83b4582ffd65cab576e84d1b502ce31a70c57f0ce9af76e3ffd9978de031
3
+ metadata.gz: 9caa7b15e9d581680796ce9780382a7b81a62366923aa97949b5dc4c8615696a
4
+ data.tar.gz: 9c27c825131b46779740cceb8aa78f8dcad774ead3b22068b41ff07586387dbf
5
5
  SHA512:
6
- metadata.gz: 9ca7d43729ca2e9b8d2012c8f1e9055832ba52a7c7abe8b14c37ad92b73af1a689dd92ec6415e2f4f1532b18a10310caee45c2370579e389914237acb2496cbb
7
- data.tar.gz: 687feaca288aec140529e59948290a4e99aae6261567953768340b0b36aa6a8920f9e2640fd0b7a8a02cb22f727b417302569fba4bfda736c0a2a0b6c04b41a1
6
+ metadata.gz: 6712bf834fa6adffa3289fdcc77cce424d035460c5dc6c7a2259c894c3b957e55624190ef86fe94786347c685c0d5249eebdc9ff3d38b4cf2721d1bcefa65fd4
7
+ data.tar.gz: 144182693223e9379d60ba6415506e1ccd30633da0a9303ae4e89565166c7ae0e300c72e17681c3092d495fc6b496b87ffa1e700c3041d4369077ecca2faa236
data/.eslintrc CHANGED
@@ -1,32 +1,7 @@
1
1
  {
2
- "root": true,
3
- "extends": ["airbnb-base", "./node_modules/@theforeman/vendor-dev/eslint.extends.js"],
4
- "plugins": [
5
- "react"
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
@@ -14,3 +14,4 @@ locale/*/*.po.time_stamp
14
14
  Gemfile.lock
15
15
  node_modules/
16
16
  package-lock.json
17
+ coverage/
@@ -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
@@ -2,6 +2,7 @@ source 'http://rubygems.org'
2
2
 
3
3
  gemspec :name => 'foreman_remote_execution'
4
4
 
5
+ gem 'rubocop', '~> 0.80.0'
5
6
  gem 'rubocop-minitest'
6
7
  gem 'rubocop-performance'
7
8
  gem 'rubocop-rails'
@@ -1,9 +1,6 @@
1
- div.infoblock {
2
- margin-bottom: 20px;
3
- line-height: 2;
4
-
1
+ .target-hosts-card {
5
2
  pre {
6
- margin-top: 5px;
3
+ white-space:pre-line;
7
4
  }
8
5
  }
9
6
 
@@ -29,3 +26,7 @@ div.infoblock {
29
26
  }
30
27
  }
31
28
  }
29
+
30
+ .text_warp{
31
+ word-wrap: break-word;
32
+ }
@@ -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 = Host.authorized(:view_hosts).find(params['host_id'])
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.search_for(*search_options)
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
- 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
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
- display_link_if_authorized(_('Host detail'), hash_for_host_path(host).merge(:auth_object => host, :permission => :view_hosts, :authorizer => job_hosts_authorizer)),
45
- display_link_if_authorized(_('Rerun on %s') % host.name, hash_for_rerun_job_invocation_path(:id => job_invocation, :host_ids => [ host.id ], :authorizer => job_hosts_authorizer)),
46
- if host_task.present?
47
- display_link_if_authorized(
48
- _('Host task'),
49
- hash_for_foreman_tasks_task_path(host_task)
50
- .merge(:auth_object => host_task, :permission => :view_foreman_tasks)
51
- )
52
- end,
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(args)
12
- proxy_id, target = args
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, target = host_kind_target
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, [proxy.id, target]])
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&.build && host&.changes&.key?('build')
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