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