foreman_remote_execution 4.1.0 → 4.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/controllers/api/v2/job_invocations_controller.rb +20 -2
- data/app/controllers/foreman_remote_execution/concerns/api/v2/registration_controller_extensions.rb +26 -0
- data/app/controllers/job_templates_controller.rb +1 -1
- data/app/lib/actions/remote_execution/run_hosts_job.rb +9 -1
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +38 -14
- data/app/models/job_invocation.rb +1 -0
- data/app/models/remote_execution_feature.rb +5 -2
- data/app/models/remote_execution_provider.rb +6 -1
- data/app/services/remote_execution_proxy_selector.rb +3 -0
- data/app/views/api/v2/job_invocations/main.json.rabl +1 -1
- data/app/views/api/v2/registration/_form.html.erb +12 -0
- data/app/views/template_invocations/_output_line_set.html.erb +1 -1
- data/app/views/templates/ssh/package_action.erb +1 -0
- data/config/routes.rb +1 -0
- data/db/migrate/20200820122057_add_proxy_selector_override_to_remote_execution_feature.rb +5 -0
- data/lib/foreman_remote_execution/engine.rb +9 -1
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/package.json +6 -6
- data/test/functional/api/v2/job_invocations_controller_test.rb +19 -0
- data/test/functional/api/v2/registration_controller_test.rb +82 -0
- data/test/unit/actions/run_hosts_job_test.rb +1 -0
- data/webpack/react_app/components/TargetingHosts/TargetingHosts.js +5 -1
- data/webpack/react_app/components/TargetingHosts/TargetingHostsPage.js +5 -1
- metadata +11 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db51f6eb1c4c3513b55e3420cd28ee22e956980ef8b82845e7e65cf5389afe32
|
4
|
+
data.tar.gz: ce148bbcf61c208f646a68153ba36331d1a994476690d4a5d37551fda47fc25b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28dda5271e680ab81d7d38aea31e250b01c930a6793417deb4d2204975298e48d14c17880699d4354662ad35381566b60e6fd04f8b2ebdb5d89599cab9bf5e74
|
7
|
+
data.tar.gz: 298f020eacc63c41e0ef3d198ba45723f629ce991931126c3cf3a446677439dccf4a1a24d1b1c14b110423964ab5f04aac44a3fb8acab10b6e5d2d4f994a9f2f
|
@@ -6,7 +6,7 @@ module Api
|
|
6
6
|
|
7
7
|
before_action :find_optional_nested_object, :only => %w{output raw_output}
|
8
8
|
before_action :find_host, :only => %w{output raw_output}
|
9
|
-
before_action :find_resource, :only => %w{show update destroy clone cancel rerun}
|
9
|
+
before_action :find_resource, :only => %w{show update destroy clone cancel rerun outputs}
|
10
10
|
|
11
11
|
wrap_parameters JobInvocation, :include => (JobInvocation.attribute_names + [:ssh])
|
12
12
|
|
@@ -137,6 +137,24 @@ module Api
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
+
api :GET, '/job_invocations/:id/outputs', N_('Get outputs of hosts in a job')
|
141
|
+
param :id, :identifier, :required => true
|
142
|
+
param :search_query, :identifier, :required => false
|
143
|
+
param :since, String, :required => false
|
144
|
+
param :raw, String, :required => false
|
145
|
+
def outputs
|
146
|
+
hosts = @job_invocation.targeting.hosts.authorized(:view_hosts, Host)
|
147
|
+
hosts = hosts.search_for(params['search_query']) if params['search_query']
|
148
|
+
raw = ActiveRecord::Type::Boolean.new.cast params['raw']
|
149
|
+
default_value = raw ? '' : []
|
150
|
+
outputs = hosts.map do |host|
|
151
|
+
host_output(@job_invocation, host, :default => default_value, :since => params['since'], :raw => raw)
|
152
|
+
.merge(host_id: host.id)
|
153
|
+
end
|
154
|
+
|
155
|
+
render :json => { :outputs => outputs }
|
156
|
+
end
|
157
|
+
|
140
158
|
private
|
141
159
|
|
142
160
|
def allowed_nested_id
|
@@ -145,7 +163,7 @@ module Api
|
|
145
163
|
|
146
164
|
def action_permission
|
147
165
|
case params[:action]
|
148
|
-
when 'output', 'raw_output'
|
166
|
+
when 'output', 'raw_output', 'outputs'
|
149
167
|
:view
|
150
168
|
when 'cancel'
|
151
169
|
:cancel
|
data/app/controllers/foreman_remote_execution/concerns/api/v2/registration_controller_extensions.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module ForemanRemoteExecution
|
2
|
+
module Concerns
|
3
|
+
module Api::V2::RegistrationControllerExtensions
|
4
|
+
module ApipieExtensions
|
5
|
+
extend Apipie::DSL::Concern
|
6
|
+
|
7
|
+
update_api(:global, :host) do
|
8
|
+
param :remote_execution_interface, String, desc: N_("Identifier of the Host interface for Remote execution")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
extend ActiveSupport::Concern
|
13
|
+
|
14
|
+
def host_setup_extension
|
15
|
+
remote_execution_interface
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def remote_execution_interface
|
20
|
+
return unless params['remote_execution_interface'].present?
|
21
|
+
|
22
|
+
@host.set_execution_interface(params['remote_execution_interface'])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -36,7 +36,7 @@ class JobTemplatesController < ::TemplatesController
|
|
36
36
|
|
37
37
|
@template = JobTemplate.import_raw(contents, :update => Foreman::Cast.to_bool(params[:imported_template][:overwrite]))
|
38
38
|
if @template&.save
|
39
|
-
flash[:
|
39
|
+
flash[:success] = _('Job template imported successfully.')
|
40
40
|
redirect_to job_templates_path(:search => "name = \"#{@template.name}\"")
|
41
41
|
else
|
42
42
|
@template ||= JobTemplate.import_raw(contents, :build_new => true)
|
@@ -65,8 +65,16 @@ module Actions
|
|
65
65
|
hosts.offset(from).limit(size)
|
66
66
|
end
|
67
67
|
|
68
|
+
def initiate
|
69
|
+
output[:host_count] = total_count
|
70
|
+
super
|
71
|
+
end
|
72
|
+
|
68
73
|
def total_count
|
69
|
-
|
74
|
+
# For compatibility with already existing tasks
|
75
|
+
return output[:total_count] unless output.has_key?(:host_count) || task.pending?
|
76
|
+
|
77
|
+
output[:host_count] || hosts.count
|
70
78
|
end
|
71
79
|
|
72
80
|
def hosts
|
@@ -44,29 +44,33 @@ module ForemanRemoteExecution
|
|
44
44
|
@execution_status_label ||= get_status(HostStatus::ExecutionStatus).to_label(options)
|
45
45
|
end
|
46
46
|
|
47
|
+
# rubocop:disable Naming/MemoizedInstanceVariableName
|
47
48
|
def host_params_hash
|
48
|
-
|
49
|
-
keys = remote_execution_ssh_keys
|
50
|
-
source = 'global'
|
51
|
-
if keys.present?
|
52
|
-
value, safe_value = params.fetch('remote_execution_ssh_keys', {}).values_at(:value, :safe_value).map { |v| [v].flatten.compact }
|
53
|
-
params['remote_execution_ssh_keys'] = {:value => value + keys, :safe_value => safe_value + keys, :source => source}
|
54
|
-
end
|
55
|
-
[:remote_execution_ssh_user, :remote_execution_effective_user_method,
|
56
|
-
:remote_execution_connect_by_ip].each do |key|
|
57
|
-
value = Setting[key]
|
58
|
-
params[key.to_s] = {:value => value, :safe_value => value, :source => source} unless params.key?(key.to_s)
|
59
|
-
end
|
60
|
-
params
|
49
|
+
@cached_rex_host_params_hash ||= extend_host_params_hash(super)
|
61
50
|
end
|
51
|
+
# rubocop:enable Naming/MemoizedInstanceVariableName
|
62
52
|
|
63
53
|
def execution_interface
|
64
54
|
get_interface_by_flag(:execution)
|
65
55
|
end
|
66
56
|
|
57
|
+
def set_execution_interface(identifier)
|
58
|
+
if interfaces.find_by(identifier: identifier).nil?
|
59
|
+
msg = (N_("Interface with the '%s' identifier was specified as a remote execution interface, however the interface was not found on the host. If the interface exists, it needs to be created in Foreman during the registration.") % identifier)
|
60
|
+
raise ActiveRecord::RecordNotFound, msg
|
61
|
+
end
|
62
|
+
|
63
|
+
# Only one interface at time can be used for REX, all other must be set to false
|
64
|
+
interfaces.each { |int| int.execution = (int.identifier == identifier) }
|
65
|
+
interfaces.each(&:save!)
|
66
|
+
end
|
67
|
+
|
67
68
|
def remote_execution_proxies(provider, authorized = true)
|
68
69
|
proxies = {}
|
69
|
-
proxies[:subnet]
|
70
|
+
proxies[:subnet] = []
|
71
|
+
proxies[:subnet] += execution_interface.subnet6.remote_execution_proxies.with_features(provider) if execution_interface&.subnet6
|
72
|
+
proxies[:subnet] += execution_interface.subnet.remote_execution_proxies.with_features(provider) if execution_interface&.subnet
|
73
|
+
proxies[:subnet].uniq!
|
70
74
|
proxies[:fallback] = smart_proxies.with_features(provider) if Setting[:remote_execution_fallback_proxy]
|
71
75
|
|
72
76
|
if Setting[:remote_execution_global_proxy]
|
@@ -102,8 +106,28 @@ module ForemanRemoteExecution
|
|
102
106
|
super(*args)
|
103
107
|
end
|
104
108
|
|
109
|
+
def clear_host_parameters_cache!
|
110
|
+
super
|
111
|
+
@cached_rex_host_params_hash = nil
|
112
|
+
end
|
113
|
+
|
105
114
|
private
|
106
115
|
|
116
|
+
def extend_host_params_hash(params)
|
117
|
+
keys = remote_execution_ssh_keys
|
118
|
+
source = 'global'
|
119
|
+
if keys.present?
|
120
|
+
value, safe_value = params.fetch('remote_execution_ssh_keys', {}).values_at(:value, :safe_value).map { |v| [v].flatten.compact }
|
121
|
+
params['remote_execution_ssh_keys'] = {:value => value + keys, :safe_value => safe_value + keys, :source => source}
|
122
|
+
end
|
123
|
+
[:remote_execution_ssh_user, :remote_execution_effective_user_method,
|
124
|
+
:remote_execution_connect_by_ip].each do |key|
|
125
|
+
value = Setting[key]
|
126
|
+
params[key.to_s] = {:value => value, :safe_value => value, :source => source} unless params.key?(key.to_s)
|
127
|
+
end
|
128
|
+
params
|
129
|
+
end
|
130
|
+
|
107
131
|
def build_required_interfaces(attrs = {})
|
108
132
|
super(attrs)
|
109
133
|
self.primary_interface.execution = true if self.execution_interface.nil?
|
@@ -22,6 +22,7 @@ class JobInvocation < ApplicationRecord
|
|
22
22
|
validates :job_category, :presence => true
|
23
23
|
validates_associated :targeting, :all_template_invocations
|
24
24
|
|
25
|
+
scoped_search :on => :id, :complete_value => true
|
25
26
|
scoped_search :on => :job_category, :complete_value => true
|
26
27
|
scoped_search :on => :description, :complete_value => true
|
27
28
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class RemoteExecutionFeature < ApplicationRecord
|
2
|
-
VALID_OPTIONS = [:provided_inputs, :description, :host_action_button, :notification_builder].freeze
|
2
|
+
VALID_OPTIONS = [:provided_inputs, :description, :host_action_button, :notification_builder, :proxy_selector_override].freeze
|
3
3
|
validates :label, :name, :presence => true, :uniqueness => true
|
4
4
|
|
5
5
|
belongs_to :job_template
|
@@ -24,8 +24,10 @@ class RemoteExecutionFeature < ApplicationRecord
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.register(label, name, options = {})
|
27
|
+
pending_migrations = ::Foreman::Plugin.registered_plugins[:foreman_remote_execution]&.pending_migrations
|
27
28
|
begin
|
28
|
-
|
29
|
+
# Let's not try to register features if rex is not registered as a plugin
|
30
|
+
return false if pending_migrations || pending_migrations.nil?
|
29
31
|
rescue ActiveRecord::NoDatabaseError => e
|
30
32
|
# just ignore the problem if DB does not exist yet (rake db:create call)
|
31
33
|
return false
|
@@ -41,6 +43,7 @@ class RemoteExecutionFeature < ApplicationRecord
|
|
41
43
|
:provided_input_names => options[:provided_inputs],
|
42
44
|
:description => options[:description],
|
43
45
|
:host_action_button => options[:host_action_button],
|
46
|
+
:proxy_selector_override => options[:proxy_selector_override],
|
44
47
|
:notification_builder => builder }
|
45
48
|
# in case DB does not have the attribute created yet but plugin initializer registers the feature, we need to skip this attribute
|
46
49
|
attrs = [ :host_action_button, :notification_builder ]
|
@@ -101,7 +101,12 @@ class RemoteExecutionProvider
|
|
101
101
|
|
102
102
|
# Return a specific proxy selector to use for running a given template
|
103
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(
|
104
|
+
def required_proxy_selector_for(template)
|
105
|
+
if template.remote_execution_features
|
106
|
+
.where(:proxy_selector_override => ::RemoteExecutionProxySelector::INTERNAL_PROXY)
|
107
|
+
.any?
|
108
|
+
::DefaultProxyProxySelector.new
|
109
|
+
end
|
105
110
|
end
|
106
111
|
end
|
107
112
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div class='form-group'>
|
2
|
+
<label class='col-md-2 control-label'>
|
3
|
+
<%= _('Remote Execution Interface') %>
|
4
|
+
<% help = _('Identifier of the Host interface for Remote execution') %>
|
5
|
+
<a rel="popover" data-content="<%= help %>" data-trigger="focus" data-container="body" data-html="true" tabindex="-1">
|
6
|
+
<span class="pficon pficon-info "></span>
|
7
|
+
</a>
|
8
|
+
</label>
|
9
|
+
<div class='col-md-4'>
|
10
|
+
<%= text_field_tag 'remote_execution_interface', params[:remote_execution_interface], class: 'form-control' %>
|
11
|
+
</div>
|
12
|
+
</div>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% output_line_set['output'].gsub("\r\n", "\n").sub(/\n\Z/, '').split("\n", -1).each do |line| %>
|
2
2
|
<%= content_tag :div, :class => 'line ' + output_line_set['output_type'], :data => { :timestamp => output_line_set['timestamp'] } do %>
|
3
3
|
|
4
|
-
<%= content_tag(:span, (@line_counter += 1).to_s.rjust(4).gsub(' ', ' ').html_safe + ':', :class => 'counter', :title => (output_line_set['timestamp'] && Time.at(output_line_set['timestamp']))) %>
|
4
|
+
<%= content_tag(:span, (@line_counter += 1).to_s.rjust(4).gsub(' ', ' ').html_safe + ':', :class => 'counter', :title => (output_line_set['timestamp'] && Time.at(output_line_set['timestamp'].to_f))) %>
|
5
5
|
<%= content_tag(:div, colorize_line(line.gsub(JobInvocationOutputHelper::COLOR_PATTERN, '').empty? ? "#{line}\n" : line).html_safe, :class => 'content') %>
|
6
6
|
<% end %>
|
7
7
|
<% end %>
|
@@ -98,6 +98,7 @@ handle_zypp_res_codes () {
|
|
98
98
|
end
|
99
99
|
-%>
|
100
100
|
[ -x "$(command -v subscription-manager)" ] && subscription-manager refresh
|
101
|
+
export DEBIAN_FRONTEND=noninteractive
|
101
102
|
apt-get -y update
|
102
103
|
apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -y <%= action %> <%= input("package") %>
|
103
104
|
<% elsif package_manager == 'zypper' -%>
|
data/config/routes.rb
CHANGED
@@ -83,7 +83,7 @@ module ForemanRemoteExecution
|
|
83
83
|
permission :create_job_invocations, { :job_invocations => [:new, :create, :refresh, :rerun, :preview_hosts],
|
84
84
|
'api/v2/job_invocations' => [:create, :rerun] }, :resource_type => 'JobInvocation'
|
85
85
|
permission :view_job_invocations, { :job_invocations => [:index, :chart, :show, :auto_complete_search], :template_invocations => [:show],
|
86
|
-
'api/v2/job_invocations' => [:index, :show, :output, :raw_output] }, :resource_type => 'JobInvocation'
|
86
|
+
'api/v2/job_invocations' => [:index, :show, :output, :raw_output, :outputs] }, :resource_type => 'JobInvocation'
|
87
87
|
permission :view_template_invocations, { :template_invocations => [:show],
|
88
88
|
'api/v2/template_invocations' => [:template_invocations] }, :resource_type => 'TemplateInvocation'
|
89
89
|
permission :create_template_invocations, {}, :resource_type => 'TemplateInvocation'
|
@@ -151,6 +151,12 @@ module ForemanRemoteExecution
|
|
151
151
|
extend_rabl_template 'api/v2/subnets/show', 'api/v2/subnets/remote_execution_proxies'
|
152
152
|
parameter_filter ::Subnet, :remote_execution_proxy_ids
|
153
153
|
describe_host { overview_buttons_provider :host_overview_buttons }
|
154
|
+
|
155
|
+
# Extend Registration module
|
156
|
+
extend_allowed_registration_vars :remote_execution_interface
|
157
|
+
extend_page 'registration/_form' do |cx|
|
158
|
+
cx.add_pagelet :global_registration, name: N_('Remote Execution'), partial: 'api/v2/registration/form', priority: 100, id: 'remote_execution_interface'
|
159
|
+
end
|
154
160
|
end
|
155
161
|
end
|
156
162
|
|
@@ -207,6 +213,8 @@ module ForemanRemoteExecution
|
|
207
213
|
ForemanRemoteExecution.register_rex_feature
|
208
214
|
|
209
215
|
::Api::V2::SubnetsController.include ::ForemanRemoteExecution::Concerns::Api::V2::SubnetsControllerExtensions
|
216
|
+
::Api::V2::RegistrationController.prepend ::ForemanRemoteExecution::Concerns::Api::V2::RegistrationControllerExtensions
|
217
|
+
::Api::V2::RegistrationController.include ::ForemanRemoteExecution::Concerns::Api::V2::RegistrationControllerExtensions::ApipieExtensions
|
210
218
|
end
|
211
219
|
|
212
220
|
initializer 'foreman_remote_execution.register_gettext', after: :load_config_initializers do |_app|
|
data/package.json
CHANGED
@@ -21,16 +21,16 @@
|
|
21
21
|
},
|
22
22
|
"devDependencies": {
|
23
23
|
"@babel/core": "^7.7.0",
|
24
|
-
"@theforeman/builder": "^4.
|
25
|
-
"@theforeman/eslint-plugin-foreman": "^4.
|
26
|
-
"@theforeman/stories": "^4.
|
27
|
-
"@theforeman/test": "^4.
|
28
|
-
"@theforeman/vendor-dev": "^4.
|
24
|
+
"@theforeman/builder": "^4.14.0",
|
25
|
+
"@theforeman/eslint-plugin-foreman": "^4.14.0",
|
26
|
+
"@theforeman/stories": "^4.14.0",
|
27
|
+
"@theforeman/test": "^4.14.0",
|
28
|
+
"@theforeman/vendor-dev": "^4.14.0",
|
29
29
|
"babel-eslint": "^10.0.0",
|
30
30
|
"eslint": "^6.8.0",
|
31
31
|
"prettier": "^1.19.1"
|
32
32
|
},
|
33
33
|
"peerDependencies": {
|
34
|
-
"@theforeman/vendor": ">= 4.
|
34
|
+
"@theforeman/vendor": ">= 4.14.0"
|
35
35
|
}
|
36
36
|
}
|
@@ -160,6 +160,25 @@ module Api
|
|
160
160
|
end
|
161
161
|
end
|
162
162
|
|
163
|
+
describe '#outputs' do
|
164
|
+
test 'should provide outputs for hosts in the job' do
|
165
|
+
get :outputs, params: { :id => @invocation.id }
|
166
|
+
result = ActiveSupport::JSON.decode(@response.body)
|
167
|
+
host_output = result['outputs'].first
|
168
|
+
assert_equal host_output['host_id'], @invocation.targeting.host_ids.first
|
169
|
+
assert_equal host_output['refresh'], true
|
170
|
+
assert_equal host_output['output'], []
|
171
|
+
assert_response :success
|
172
|
+
end
|
173
|
+
|
174
|
+
test 'should provide outputs for hosts in the job matching a search query' do
|
175
|
+
get :outputs, params: { :id => @invocation.id, :search_query => "name = definitely_not_in_the_job" }
|
176
|
+
result = ActiveSupport::JSON.decode(@response.body)
|
177
|
+
assert_equal result['outputs'], []
|
178
|
+
assert_response :success
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
163
182
|
describe 'raw output' do
|
164
183
|
let(:fake_output) do
|
165
184
|
(1..5).map do |i|
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'test_plugin_helper'
|
2
|
+
|
3
|
+
module Api
|
4
|
+
module V2
|
5
|
+
# Tests for the extra methods to play roles on a Host
|
6
|
+
class RegistrationControllerTest < ActionController::TestCase
|
7
|
+
describe 'host registration' do
|
8
|
+
let(:organization) { FactoryBot.create(:organization) }
|
9
|
+
let(:tax_location) { FactoryBot.create(:location) }
|
10
|
+
let(:template_kind) { template_kinds(:registration) }
|
11
|
+
let(:registration_template) do
|
12
|
+
FactoryBot.create(
|
13
|
+
:provisioning_template,
|
14
|
+
template_kind: template_kind,
|
15
|
+
template: 'template content <%= @host.name %>',
|
16
|
+
locations: [tax_location],
|
17
|
+
organizations: [organization]
|
18
|
+
)
|
19
|
+
end
|
20
|
+
let(:os) do
|
21
|
+
FactoryBot.create(
|
22
|
+
:operatingsystem,
|
23
|
+
:with_associations,
|
24
|
+
family: 'Redhat',
|
25
|
+
provisioning_templates: [
|
26
|
+
registration_template,
|
27
|
+
]
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
let(:host_params) do
|
32
|
+
{ host: { name: 'centos-test.example.com',
|
33
|
+
managed: false, build: false,
|
34
|
+
organization_id: organization.id,
|
35
|
+
location_id: tax_location.id,
|
36
|
+
operatingsystem_id: os.id } }
|
37
|
+
end
|
38
|
+
|
39
|
+
setup do
|
40
|
+
FactoryBot.create(
|
41
|
+
:os_default_template,
|
42
|
+
template_kind: template_kind,
|
43
|
+
provisioning_template: registration_template,
|
44
|
+
operatingsystem: os
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'remote_execution_interface' do
|
49
|
+
setup do
|
50
|
+
@host = Host.create(host_params[:host])
|
51
|
+
@interface0 = FactoryBot.create(:nic_managed, host: @host, identifier: 'dummy0', execution: false)
|
52
|
+
end
|
53
|
+
|
54
|
+
test 'with existing interface' do
|
55
|
+
params = host_params.merge(remote_execution_interface: @interface0.identifier)
|
56
|
+
|
57
|
+
post :host, params: params, session: set_session_user
|
58
|
+
assert_response :success
|
59
|
+
assert @interface0.reload.execution
|
60
|
+
end
|
61
|
+
|
62
|
+
test 'with not-existing interface' do
|
63
|
+
params = host_params.merge(remote_execution_interface: 'dummy999')
|
64
|
+
|
65
|
+
post :host, params: params, session: set_session_user
|
66
|
+
assert_response :not_found
|
67
|
+
end
|
68
|
+
|
69
|
+
test 'with multiple interfaces' do
|
70
|
+
interface1 = FactoryBot.create(:nic_managed, host: @host, identifier: 'dummy1', execution: false)
|
71
|
+
params = host_params.merge(remote_execution_interface: interface1.identifier)
|
72
|
+
|
73
|
+
post :host, params: params, session: set_session_user
|
74
|
+
assert_response :success
|
75
|
+
refute @interface0.reload.execution
|
76
|
+
assert interface1.reload.execution
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -51,8 +51,12 @@ const TargetingHosts = ({ apiStatus, items }) => {
|
|
51
51
|
};
|
52
52
|
|
53
53
|
TargetingHosts.propTypes = {
|
54
|
-
apiStatus: PropTypes.string
|
54
|
+
apiStatus: PropTypes.string,
|
55
55
|
items: PropTypes.array.isRequired,
|
56
56
|
};
|
57
57
|
|
58
|
+
TargetingHosts.defaultProps = {
|
59
|
+
apiStatus: null,
|
60
|
+
};
|
61
|
+
|
58
62
|
export default TargetingHosts;
|
@@ -52,11 +52,15 @@ const TargetingHostsPage = ({
|
|
52
52
|
TargetingHostsPage.propTypes = {
|
53
53
|
handleSearch: PropTypes.func.isRequired,
|
54
54
|
searchQuery: PropTypes.string.isRequired,
|
55
|
-
apiStatus: PropTypes.string
|
55
|
+
apiStatus: PropTypes.string,
|
56
56
|
items: PropTypes.array.isRequired,
|
57
57
|
totalHosts: PropTypes.number.isRequired,
|
58
58
|
pagination: PropTypes.object.isRequired,
|
59
59
|
handlePagination: PropTypes.func.isRequired,
|
60
60
|
};
|
61
61
|
|
62
|
+
TargetingHostsPage.defaultProps = {
|
63
|
+
apiStatus: null,
|
64
|
+
};
|
65
|
+
|
62
66
|
export default TargetingHostsPage;
|
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: 4.
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Foreman Remote Execution team
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-09
|
11
|
+
date: 2020-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deface
|
@@ -154,6 +154,7 @@ files:
|
|
154
154
|
- app/controllers/concerns/foreman/controller/parameters/job_template.rb
|
155
155
|
- app/controllers/concerns/foreman/controller/parameters/remote_execution_feature.rb
|
156
156
|
- app/controllers/concerns/foreman/controller/parameters/targeting.rb
|
157
|
+
- app/controllers/foreman_remote_execution/concerns/api/v2/registration_controller_extensions.rb
|
157
158
|
- app/controllers/foreman_remote_execution/concerns/api/v2/subnets_controller_extensions.rb
|
158
159
|
- app/controllers/job_invocations_controller.rb
|
159
160
|
- app/controllers/job_templates_controller.rb
|
@@ -226,6 +227,7 @@ files:
|
|
226
227
|
- app/views/api/v2/job_templates/main.json.rabl
|
227
228
|
- app/views/api/v2/job_templates/show.json.rabl
|
228
229
|
- app/views/api/v2/job_templates/update.json.rabl
|
230
|
+
- app/views/api/v2/registration/_form.html.erb
|
229
231
|
- app/views/api/v2/remote_execution_features/base.json.rabl
|
230
232
|
- app/views/api/v2/remote_execution_features/index.json.rabl
|
231
233
|
- app/views/api/v2/remote_execution_features/main.json.rabl
|
@@ -328,6 +330,7 @@ files:
|
|
328
330
|
- db/migrate/20180913101042_add_randomized_ordering_to_targeting.rb
|
329
331
|
- db/migrate/20190111153330_remove_remote_execution_without_proxy_setting.rb
|
330
332
|
- db/migrate/20200623073022_rename_sudo_password_to_effective_user_password.rb
|
333
|
+
- db/migrate/20200820122057_add_proxy_selector_override_to_remote_execution_feature.rb
|
331
334
|
- db/seeds.d/100-assign_features_with_templates.rb
|
332
335
|
- db/seeds.d/20-permissions.rb
|
333
336
|
- db/seeds.d/50-notification_blueprints.rb
|
@@ -376,6 +379,7 @@ files:
|
|
376
379
|
- test/functional/api/v2/foreign_input_sets_controller_test.rb
|
377
380
|
- test/functional/api/v2/job_invocations_controller_test.rb
|
378
381
|
- test/functional/api/v2/job_templates_controller_test.rb
|
382
|
+
- test/functional/api/v2/registration_controller_test.rb
|
379
383
|
- test/functional/api/v2/remote_execution_features_controller_test.rb
|
380
384
|
- test/functional/api/v2/template_invocations_controller_test.rb
|
381
385
|
- test/functional/cockpit_controller_test.rb
|
@@ -443,7 +447,7 @@ homepage: https://github.com/theforeman/foreman_remote_execution
|
|
443
447
|
licenses:
|
444
448
|
- GPL-3.0
|
445
449
|
metadata: {}
|
446
|
-
post_install_message:
|
450
|
+
post_install_message:
|
447
451
|
rdoc_options: []
|
448
452
|
require_paths:
|
449
453
|
- lib
|
@@ -458,8 +462,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
458
462
|
- !ruby/object:Gem::Version
|
459
463
|
version: '0'
|
460
464
|
requirements: []
|
461
|
-
rubygems_version: 3.
|
462
|
-
signing_key:
|
465
|
+
rubygems_version: 3.1.2
|
466
|
+
signing_key:
|
463
467
|
specification_version: 4
|
464
468
|
summary: A plugin bringing remote execution to the Foreman, completing the config
|
465
469
|
management functionality with remote management functionality.
|
@@ -470,6 +474,7 @@ test_files:
|
|
470
474
|
- test/functional/api/v2/foreign_input_sets_controller_test.rb
|
471
475
|
- test/functional/api/v2/job_invocations_controller_test.rb
|
472
476
|
- test/functional/api/v2/job_templates_controller_test.rb
|
477
|
+
- test/functional/api/v2/registration_controller_test.rb
|
473
478
|
- test/functional/api/v2/remote_execution_features_controller_test.rb
|
474
479
|
- test/functional/api/v2/template_invocations_controller_test.rb
|
475
480
|
- test/functional/cockpit_controller_test.rb
|