foreman_remote_execution 3.0.2 → 3.2.2
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/.hound.yml +2 -1
- data/.rubocop.yml +80 -50
- data/.rubocop_todo.yml +113 -73
- data/Gemfile +4 -0
- data/app/controllers/api/v2/foreign_input_sets_controller.rb +3 -2
- data/app/controllers/api/v2/job_invocations_controller.rb +12 -7
- data/app/controllers/api/v2/job_templates_controller.rb +3 -2
- data/app/controllers/api/v2/remote_execution_features_controller.rb +3 -2
- data/app/controllers/api/v2/template_invocations_controller.rb +5 -2
- data/app/controllers/cockpit_controller.rb +1 -0
- data/app/controllers/concerns/foreman/controller/parameters/foreign_input_set.rb +1 -1
- data/app/controllers/concerns/foreman/controller/parameters/job_template.rb +4 -4
- data/app/controllers/job_invocations_controller.rb +10 -6
- data/app/controllers/job_templates_controller.rb +1 -1
- data/app/controllers/remote_execution_features_controller.rb +3 -2
- data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +16 -5
- data/app/helpers/job_invocations_chart_helper.rb +13 -10
- data/app/helpers/job_invocations_helper.rb +19 -6
- data/app/helpers/remote_execution_helper.rb +49 -48
- data/app/lib/actions/remote_execution/run_host_job.rb +5 -6
- data/app/lib/actions/remote_execution/run_hosts_job.rb +2 -2
- data/app/lib/foreman_remote_execution/renderer/scope/input.rb +1 -0
- data/app/lib/proxy_api/remote_execution_ssh.rb +6 -0
- data/app/models/concerns/foreman_remote_execution/errors_flattener.rb +0 -2
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +4 -6
- data/app/models/concerns/foreman_remote_execution/nic_extensions.rb +1 -0
- data/app/models/concerns/foreman_remote_execution/orchestration/ssh.rb +63 -0
- data/app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb +5 -0
- data/app/models/foreign_input_set.rb +3 -2
- data/app/models/host_status/execution_status.rb +9 -1
- data/app/models/input_template_renderer.rb +1 -1
- data/app/models/job_invocation.rb +10 -12
- data/app/models/job_invocation_composer.rb +20 -14
- data/app/models/job_invocation_task_group.rb +1 -1
- data/app/models/job_template.rb +3 -3
- data/app/models/remote_execution_feature.rb +0 -2
- data/app/models/remote_execution_provider.rb +4 -2
- data/app/models/setting/remote_execution.rb +54 -56
- data/app/models/ssh_execution_provider.rb +2 -2
- data/app/models/targeting.rb +1 -0
- data/app/models/template_invocation.rb +2 -3
- data/app/views/api/v2/job_invocations/base.json.rabl +1 -1
- data/app/views/api/v2/job_invocations/main.json.rabl +7 -4
- data/app/views/job_invocations/_card_results.html.erb +1 -0
- data/app/views/job_invocations/_card_target_hosts.html.erb +12 -0
- data/app/views/job_invocations/_card_user_input.html.erb +1 -1
- data/app/views/job_invocations/_form.html.erb +3 -2
- data/app/views/job_invocations/_host_status_td.html.erb +1 -1
- data/app/views/job_invocations/_rerun_taxonomies.html.erb +22 -0
- data/app/views/job_invocations/_tab_overview.html.erb +1 -1
- data/app/views/job_invocations/_user_input.html.erb +1 -1
- data/app/views/job_invocations/show.html.erb +3 -1
- data/config/routes.rb +2 -1
- data/db/migrate/20151215114631_add_host_id_to_template_invocation.rb +1 -0
- data/db/migrate/20180110104432_rename_template_invocation_permission.rb +1 -0
- data/db/seeds.d/50-notification_blueprints.rb +4 -4
- data/db/seeds.d/90-bookmarks.rb +1 -0
- data/extra/cockpit/foreman-cockpit-session +7 -2
- data/foreman_remote_execution.gemspec +1 -1
- data/lib/foreman_remote_execution/engine.rb +20 -17
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/locale/action_names.rb +4 -3
- data/locale/de/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/de/foreman_remote_execution.po +65 -16
- data/locale/en/foreman_remote_execution.po +63 -15
- data/locale/en_GB/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/en_GB/foreman_remote_execution.po +64 -15
- data/locale/es/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/es/foreman_remote_execution.po +66 -17
- data/locale/foreman_remote_execution.pot +193 -148
- data/locale/fr/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/fr/foreman_remote_execution.po +66 -17
- data/locale/ja/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ja/foreman_remote_execution.po +66 -17
- data/locale/ko/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ko/foreman_remote_execution.po +65 -15
- data/locale/pt_BR/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/pt_BR/foreman_remote_execution.po +66 -17
- data/locale/ru/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ru/foreman_remote_execution.po +65 -18
- data/locale/zh_CN/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_CN/foreman_remote_execution.po +66 -17
- data/locale/zh_TW/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_TW/foreman_remote_execution.po +65 -16
- data/package.json +2 -3
- data/test/benchmark/run_hosts_job_benchmark.rb +1 -1
- data/test/factories/foreman_remote_execution_factories.rb +1 -1
- data/test/functional/api/v2/job_invocations_controller_test.rb +51 -23
- data/test/functional/api/v2/job_templates_controller_test.rb +1 -1
- data/test/functional/api/v2/remote_execution_features_controller_test.rb +2 -2
- data/test/functional/api/v2/template_invocations_controller_test.rb +4 -4
- data/test/functional/job_invocations_controller_test.rb +23 -11
- data/test/functional/job_templates_controller_test.rb +1 -1
- data/test/models/orchestration/ssh_test.rb +56 -0
- data/test/unit/actions/run_hosts_job_test.rb +8 -8
- data/test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb +3 -3
- data/test/unit/concerns/host_extensions_test.rb +26 -19
- data/test/unit/concerns/nic_extensions_test.rb +1 -1
- data/test/unit/execution_task_status_mapper_test.rb +10 -10
- data/test/unit/input_template_renderer_test.rb +77 -77
- data/test/unit/job_invocation_composer_test.rb +100 -96
- data/test/unit/job_invocation_test.rb +29 -29
- data/test/unit/job_template_effective_user_test.rb +3 -3
- data/test/unit/job_template_test.rb +31 -31
- data/test/unit/remote_execution_feature_test.rb +19 -19
- data/test/unit/remote_execution_provider_test.rb +33 -30
- data/test/unit/renderer_scope_input.rb +6 -6
- data/test/unit/targeting_test.rb +6 -6
- data/test/unit/template_invocation_input_value_test.rb +3 -3
- data/webpack/index.js +0 -15
- metadata +8 -4
data/Gemfile
CHANGED
|
@@ -18,7 +18,8 @@ module Api
|
|
|
18
18
|
api :GET, '/templates/:template_id/foreign_input_sets/:id', N_('Show foreign input set details')
|
|
19
19
|
param :template_id, :identifier, :required => true
|
|
20
20
|
param :id, :identifier, :required => true
|
|
21
|
-
def show
|
|
21
|
+
def show
|
|
22
|
+
end
|
|
22
23
|
|
|
23
24
|
def_param_group :foreign_input_set do
|
|
24
25
|
param :foreign_input_set, Hash, :required => true, :action_aware => true do
|
|
@@ -50,7 +51,7 @@ module Api
|
|
|
50
51
|
param :id, :identifier, :required => true
|
|
51
52
|
param_group :foreign_input_set
|
|
52
53
|
def update
|
|
53
|
-
process_response @foreign_input_set.
|
|
54
|
+
process_response @foreign_input_set.update(foreign_input_set_params)
|
|
54
55
|
end
|
|
55
56
|
|
|
56
57
|
def resource_name(nested_resource = nil)
|
|
@@ -18,9 +18,13 @@ module Api
|
|
|
18
18
|
|
|
19
19
|
api :GET, '/job_invocations/:id', N_('Show job invocation')
|
|
20
20
|
param :id, :identifier, :required => true
|
|
21
|
-
def show
|
|
21
|
+
def show
|
|
22
|
+
@hosts = @job_invocation.targeting.hosts.authorized(:view_hosts, Host)
|
|
23
|
+
@template_invocations = @job_invocation.template_invocations
|
|
24
|
+
.where(host: @hosts)
|
|
25
|
+
.includes(:input_values)
|
|
26
|
+
end
|
|
22
27
|
|
|
23
|
-
# rubocop:disable Metrics/BlockLength
|
|
24
28
|
def_param_group :job_invocation do
|
|
25
29
|
param :job_invocation, Hash, :required => true, :action_aware => true do
|
|
26
30
|
param :job_template_id, String, :required => false, :desc => N_('The job template to use, parameter is required unless feature was specified')
|
|
@@ -29,8 +33,8 @@ module Api
|
|
|
29
33
|
param :inputs, Hash, :required => false, :desc => N_('Inputs to use')
|
|
30
34
|
param :ssh, Hash, :desc => N_('SSH provider specific options') do
|
|
31
35
|
param :effective_user, String,
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
:required => false,
|
|
37
|
+
:desc => N_('What user should be used to run the script (using sudo-like mechanisms). Defaults to a template parameter or global setting.')
|
|
34
38
|
end
|
|
35
39
|
|
|
36
40
|
param :recurrence, Hash, :desc => N_('Create a recurring job') do
|
|
@@ -107,7 +111,7 @@ module Api
|
|
|
107
111
|
render :json => { :cancelled => result, :id => @job_invocation.id }
|
|
108
112
|
else
|
|
109
113
|
render :json => { :message => _('The job could not be cancelled.') },
|
|
110
|
-
:status =>
|
|
114
|
+
:status => :unprocessable_entity
|
|
111
115
|
end
|
|
112
116
|
end
|
|
113
117
|
|
|
@@ -122,7 +126,7 @@ module Api
|
|
|
122
126
|
process_response @job_invocation
|
|
123
127
|
else
|
|
124
128
|
render :json => { :error => _('Could not rerun job %{id} because its template could not be found') % { :id => composer.reruns } },
|
|
125
|
-
:status =>
|
|
129
|
+
:status => :not_found
|
|
126
130
|
end
|
|
127
131
|
end
|
|
128
132
|
|
|
@@ -146,7 +150,7 @@ module Api
|
|
|
146
150
|
end
|
|
147
151
|
|
|
148
152
|
def find_host
|
|
149
|
-
@host =
|
|
153
|
+
@host = @nested_obj.targeting.hosts.authorized(:view_hosts, Host).find(params['host_id'])
|
|
150
154
|
rescue ActiveRecord::RecordNotFound
|
|
151
155
|
not_found({ :error => { :message => (_("Host with id '%{id}' was not found") % { :id => params['host_id'] }) } })
|
|
152
156
|
end
|
|
@@ -159,6 +163,7 @@ module Api
|
|
|
159
163
|
|
|
160
164
|
def job_invocation_params
|
|
161
165
|
return @job_invocation_params if @job_invocation_params.present?
|
|
166
|
+
|
|
162
167
|
job_invocation_params = params.fetch(:job_invocation, {}).dup
|
|
163
168
|
if job_invocation_params.key?(:ssh)
|
|
164
169
|
job_invocation_params.merge!(job_invocation_params.delete(:ssh).permit(:effective_user))
|
|
@@ -42,7 +42,8 @@ module Api
|
|
|
42
42
|
|
|
43
43
|
api :GET, '/job_templates/:id', N_('Show job template details')
|
|
44
44
|
param :id, :identifier, :required => true
|
|
45
|
-
def show
|
|
45
|
+
def show
|
|
46
|
+
end
|
|
46
47
|
|
|
47
48
|
def_param_group :job_template do
|
|
48
49
|
param :job_template, Hash, :required => true, :action_aware => true do
|
|
@@ -78,7 +79,7 @@ module Api
|
|
|
78
79
|
param :id, :identifier, :required => true
|
|
79
80
|
param_group :job_template
|
|
80
81
|
def update
|
|
81
|
-
process_response @job_template.
|
|
82
|
+
process_response @job_template.update(job_template_params)
|
|
82
83
|
end
|
|
83
84
|
|
|
84
85
|
api :GET, '/job_templates/revision'
|
|
@@ -13,7 +13,8 @@ module Api
|
|
|
13
13
|
|
|
14
14
|
api :GET, '/remote_execution_features/:id', N_('Show remote execution feature')
|
|
15
15
|
param :id, :identifier, :required => true
|
|
16
|
-
def show
|
|
16
|
+
def show
|
|
17
|
+
end
|
|
17
18
|
|
|
18
19
|
def_param_group :remote_execution_feature do
|
|
19
20
|
param :remote_execution_feature, Hash, :required => true, :action_aware => true do
|
|
@@ -25,7 +26,7 @@ module Api
|
|
|
25
26
|
param :id, :identifier, :required => true
|
|
26
27
|
param_group :remote_execution_feature
|
|
27
28
|
def update
|
|
28
|
-
process_response @remote_execution_feature.
|
|
29
|
+
process_response @remote_execution_feature.update(remote_execution_feature_params)
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
private
|
|
@@ -7,7 +7,7 @@ module Api
|
|
|
7
7
|
before_action :find_job_invocation, :only => %w{template_invocations}
|
|
8
8
|
|
|
9
9
|
api :GET, '/job_invocations/:job_invocation_id/template_invocations',
|
|
10
|
-
|
|
10
|
+
N_('List template invocations belonging to job invocation')
|
|
11
11
|
param_group :search_and_pagination, ::Api::V2::BaseController
|
|
12
12
|
param :job_invocation_id, :identifier, :required => true
|
|
13
13
|
def template_invocations
|
|
@@ -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
|
|
@@ -5,7 +5,7 @@ module ::Foreman::Controller::Parameters::ForeignInputSet
|
|
|
5
5
|
def foreign_input_set_params_filter
|
|
6
6
|
Foreman::ParameterFilter.new(::ForeignInputSet).tap do |filter|
|
|
7
7
|
filter.permit_by_context(:id, :_destroy, :template_id, :target_template_id, :include_all, :include, :exclude,
|
|
8
|
-
|
|
8
|
+
:nested => true)
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -9,16 +9,16 @@ module Foreman::Controller::Parameters::JobTemplate
|
|
|
9
9
|
def job_template_effective_user_filter
|
|
10
10
|
Foreman::ParameterFilter.new(::JobTemplateEffectiveUser).tap do |filter|
|
|
11
11
|
filter.permit_by_context(:value, :current_user, :overridable,
|
|
12
|
-
|
|
12
|
+
:nested => true)
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def job_template_params_filter
|
|
17
17
|
Foreman::ParameterFilter.new(::TemplateInput).tap do |filter|
|
|
18
18
|
filter.permit :job_category, :provider_type, :description_format, :execution_timeout_interval,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
:effective_user_attributes => [job_template_effective_user_filter],
|
|
20
|
+
:template_inputs_attributes => [template_input_params_filter],
|
|
21
|
+
:foreign_input_sets_attributes => [foreign_input_set_params_filter]
|
|
22
22
|
add_template_params_filter(filter)
|
|
23
23
|
add_taxonomix_params_filter(filter)
|
|
24
24
|
end
|
|
@@ -3,15 +3,15 @@ class JobInvocationsController < ApplicationController
|
|
|
3
3
|
include ::ForemanTasks::Concerns::Parameters::Triggering
|
|
4
4
|
include ::JobInvocationsChartHelper
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
def new
|
|
8
7
|
return @composer = prepare_composer if params[:feature].present?
|
|
8
|
+
|
|
9
9
|
ui_params = {
|
|
10
10
|
:host_ids => params[:host_ids],
|
|
11
11
|
:targeting => {
|
|
12
12
|
:targeting_type => Targeting::STATIC_TYPE,
|
|
13
|
-
:bookmark_id => params[:bookmark_id]
|
|
14
|
-
}
|
|
13
|
+
:bookmark_id => params[:bookmark_id],
|
|
14
|
+
},
|
|
15
15
|
}
|
|
16
16
|
# replace an empty string search with a dummy search query to match all hosts
|
|
17
17
|
# but only if search query was entered (based on presence of :search parameter)
|
|
@@ -24,8 +24,8 @@ class JobInvocationsController < ApplicationController
|
|
|
24
24
|
ui_params[:job_invocation] = {
|
|
25
25
|
:job_category => template.job_category,
|
|
26
26
|
:providers => {
|
|
27
|
-
template.provider_type => {:job_template_id => template.id}
|
|
28
|
-
}
|
|
27
|
+
template.provider_type => {:job_template_id => template.id},
|
|
28
|
+
},
|
|
29
29
|
}
|
|
30
30
|
end
|
|
31
31
|
|
|
@@ -35,6 +35,8 @@ class JobInvocationsController < ApplicationController
|
|
|
35
35
|
def rerun
|
|
36
36
|
job_invocation = resource_base.find(params[:id])
|
|
37
37
|
@composer = JobInvocationComposer.from_job_invocation(job_invocation, params)
|
|
38
|
+
@job_organization = Taxonomy.find_by(id: job_invocation.task.input[:current_organization_id])
|
|
39
|
+
@job_location = Taxonomy.find_by(id: job_invocation.task.input[:current_location_id])
|
|
38
40
|
render :action => 'new'
|
|
39
41
|
end
|
|
40
42
|
|
|
@@ -58,6 +60,8 @@ class JobInvocationsController < ApplicationController
|
|
|
58
60
|
.where(:template_invocations => { :job_invocation_id => @job_invocation.id})
|
|
59
61
|
end
|
|
60
62
|
@hosts = resource_base_search_and_page
|
|
63
|
+
@job_organization = Taxonomy.find_by(id: @job_invocation.task.input[:current_organization_id])
|
|
64
|
+
@job_location = Taxonomy.find_by(id: @job_invocation.task.input[:current_location_id])
|
|
61
65
|
end
|
|
62
66
|
|
|
63
67
|
def index
|
|
@@ -79,7 +83,7 @@ class JobInvocationsController < ApplicationController
|
|
|
79
83
|
:success => @job_invocation.progress_report[:success],
|
|
80
84
|
:cancelled => @job_invocation.progress_report[:cancelled],
|
|
81
85
|
:failed => @job_invocation.progress_report[:error],
|
|
82
|
-
:pending => @job_invocation.progress_report[:pending]
|
|
86
|
+
:pending => @job_invocation.progress_report[:pending],
|
|
83
87
|
},
|
|
84
88
|
}
|
|
85
89
|
end
|
|
@@ -35,7 +35,7 @@ class JobTemplatesController < ::TemplatesController
|
|
|
35
35
|
contents = params.fetch(:imported_template, {}).fetch(:template, nil).try(:read)
|
|
36
36
|
|
|
37
37
|
@template = JobTemplate.import_raw(contents, :update => Foreman::Cast.to_bool(params[:imported_template][:overwrite]))
|
|
38
|
-
if @template
|
|
38
|
+
if @template&.save
|
|
39
39
|
flash[:notice] = _('Job template imported successfully.')
|
|
40
40
|
redirect_to job_templates_path(:search => "name = \"#{@template.name}\"")
|
|
41
41
|
else
|
|
@@ -6,10 +6,11 @@ class RemoteExecutionFeaturesController < ::ApplicationController
|
|
|
6
6
|
@remote_execution_features = resource_base.all
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
def show
|
|
9
|
+
def show
|
|
10
|
+
end
|
|
10
11
|
|
|
11
12
|
def update
|
|
12
|
-
if @remote_execution_feature.
|
|
13
|
+
if @remote_execution_feature.update(remote_execution_feature_params)
|
|
13
14
|
process_success :object => @remote_execution_feature
|
|
14
15
|
else
|
|
15
16
|
process_error :object => @remote_execution_feature
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
module ForemanRemoteExecution
|
|
2
2
|
module HostsHelperExtensions
|
|
3
|
+
def host_overview_buttons(host)
|
|
4
|
+
[
|
|
5
|
+
{ :button => link_to_if_authorized(_("Jobs"), hash_for_job_invocations_path(search: "host=#{host.name}"), :title => _("Job invocations"), :class => 'btn btn-default'), :priority => 200 },
|
|
6
|
+
]
|
|
7
|
+
end
|
|
8
|
+
|
|
3
9
|
def multiple_actions
|
|
4
10
|
super + [ [_('Schedule Remote Job'), new_job_invocation_path, false] ]
|
|
5
11
|
end
|
|
6
12
|
|
|
7
13
|
def schedule_job_multi_button(*args)
|
|
8
|
-
host_features =
|
|
9
|
-
link_to(_('%s') % feature.name, job_invocations_path(:host_ids => [args.first.id], :feature => feature.label), :method => :post)
|
|
10
|
-
end
|
|
14
|
+
host_features = rex_host_features(*args)
|
|
11
15
|
|
|
12
16
|
if host_features.present?
|
|
13
17
|
action_buttons(schedule_job_button(*args), *host_features)
|
|
@@ -16,19 +20,26 @@ module ForemanRemoteExecution
|
|
|
16
20
|
end
|
|
17
21
|
end
|
|
18
22
|
|
|
23
|
+
def rex_host_features(*args)
|
|
24
|
+
RemoteExecutionFeature.with_host_action_button.order(:label).map do |feature|
|
|
25
|
+
link_to(_('%s') % feature.name, job_invocations_path(:host_ids => [args.first.id], :feature => feature.label), :method => :post)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
19
29
|
def schedule_job_button(*args)
|
|
20
30
|
link_to(_('Schedule Remote Job'), new_job_invocation_path(:host_ids => [args.first.id]), :id => :run_button, :class => 'btn btn-default')
|
|
21
31
|
end
|
|
22
32
|
|
|
23
33
|
def web_console_button(host, *args)
|
|
24
34
|
return unless authorized_for(permission: 'cockpit_hosts', auth_object: host)
|
|
35
|
+
|
|
25
36
|
url = SSHExecutionProvider.cockpit_url_for_host(host.name)
|
|
26
|
-
url ? link_to(_('Web Console'), url, :class => 'btn btn-default', :id => :'web-console-button') : nil
|
|
37
|
+
url ? link_to(_('Web Console'), url, :class => 'btn btn-default', :id => :'web-console-button', :target => '_new') : nil
|
|
27
38
|
end
|
|
28
39
|
|
|
29
40
|
def host_title_actions(*args)
|
|
30
41
|
title_actions(button_group(schedule_job_multi_button(*args)),
|
|
31
|
-
|
|
42
|
+
button_group(web_console_button(*args)))
|
|
32
43
|
super(*args)
|
|
33
44
|
end
|
|
34
45
|
end
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
module JobInvocationsChartHelper
|
|
4
4
|
def job_invocation_chart(invocation)
|
|
5
5
|
donut_chart('#status_chart',
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
job_invocation_data(invocation)[:columns],
|
|
7
|
+
job_invocation_data(invocation)[:groups])
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def job_invocation_data(invocation)
|
|
11
11
|
return @job_invocation_data if @job_invocation_data.present?
|
|
12
|
+
|
|
12
13
|
progress_report = invocation.progress_report
|
|
13
14
|
success = progress_report[:success]
|
|
14
15
|
cancelled = progress_report[:cancelled]
|
|
@@ -36,6 +37,8 @@ module JobInvocationsChartHelper
|
|
|
36
37
|
_('running %{percent}%%') % {:percent => percent}
|
|
37
38
|
when HostStatus::ExecutionStatus::OK
|
|
38
39
|
_('succeeded')
|
|
40
|
+
when HostStatus::ExecutionStatus::CANCELLED
|
|
41
|
+
_('cancelled')
|
|
39
42
|
when HostStatus::ExecutionStatus::ERROR
|
|
40
43
|
_('failed')
|
|
41
44
|
else
|
|
@@ -45,26 +48,26 @@ module JobInvocationsChartHelper
|
|
|
45
48
|
|
|
46
49
|
def job_invocation_success_status
|
|
47
50
|
icon_text('ok',
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
@job_invocation_data[0][1],
|
|
52
|
+
:kind => 'pficon')
|
|
50
53
|
end
|
|
51
54
|
|
|
52
55
|
def job_invocation_failed_status
|
|
53
56
|
icon_text('error-circle-o',
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
@job_invocation_data[1][1],
|
|
58
|
+
:kind => 'pficon')
|
|
56
59
|
end
|
|
57
60
|
|
|
58
61
|
def job_invocation_pending_status
|
|
59
62
|
icon_text('running',
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
@job_invocation_data[2][1],
|
|
64
|
+
:kind => 'pficon')
|
|
62
65
|
end
|
|
63
66
|
|
|
64
67
|
def job_invocation_cancelled_status
|
|
65
68
|
icon_text('close',
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
@job_invocation_data[3][1],
|
|
70
|
+
:kind => 'pficon')
|
|
68
71
|
end
|
|
69
72
|
|
|
70
73
|
def task_failed?(task)
|
|
@@ -15,7 +15,7 @@ module JobInvocationsHelper
|
|
|
15
15
|
def job_invocations_buttons
|
|
16
16
|
[
|
|
17
17
|
documentation_button_rex('3.2ExecutingaJob'),
|
|
18
|
-
display_link_if_authorized(_('Run Job'), hash_for_new_job_invocation_path)
|
|
18
|
+
display_link_if_authorized(_('Run Job'), hash_for_new_job_invocation_path),
|
|
19
19
|
]
|
|
20
20
|
end
|
|
21
21
|
|
|
@@ -25,11 +25,11 @@ module JobInvocationsHelper
|
|
|
25
25
|
link_content = template_name + ' - ' + provider + ' ' +
|
|
26
26
|
icon_text('edit', '', :kind => 'pficon')
|
|
27
27
|
link_to_if_authorized(link_content,
|
|
28
|
-
|
|
28
|
+
hash_for_edit_job_template_path(:id => template.id))
|
|
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',
|
|
@@ -41,10 +41,23 @@ module JobInvocationsHelper
|
|
|
41
41
|
def collapsed_preview(target)
|
|
42
42
|
title = target.try(:name) || 'N/A'
|
|
43
43
|
content_tag(:h5,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
:class => "expander collapsed out",
|
|
45
|
+
:data => { :toggle => 'collapse',
|
|
46
|
+
:target => "#preview_#{target.id}" }) do
|
|
47
47
|
content_tag(:span, '', :class => 'caret') + title
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
|
+
|
|
51
|
+
def show_job_organization(organization)
|
|
52
|
+
organization.presence || _('Any Organization')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def show_job_location(location)
|
|
56
|
+
location.presence || _('Any Location')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def input_safe_value(input)
|
|
60
|
+
template_input = input.template_input
|
|
61
|
+
template_input.respond_to?(:hidden_value) && template_input.hidden_value ? '*' * 5 : input.value
|
|
62
|
+
end
|
|
50
63
|
end
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# rubocop:disable Metrics/ModuleLength
|
|
2
1
|
module RemoteExecutionHelper
|
|
3
2
|
def providers_options
|
|
4
3
|
RemoteExecutionProvider.providers.map { |key, provider| [ key, _(provider.humanized_name) ] }
|
|
@@ -14,9 +13,13 @@ module RemoteExecutionHelper
|
|
|
14
13
|
end
|
|
15
14
|
end
|
|
16
15
|
|
|
17
|
-
def template_invocation_status(task)
|
|
16
|
+
def template_invocation_status(task, parent_task)
|
|
18
17
|
if task.nil?
|
|
19
|
-
|
|
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
|
|
20
23
|
elsif task.state == 'running'
|
|
21
24
|
icon_text('running', _('running'), :kind => 'pficon')
|
|
22
25
|
elsif task.state == 'planned'
|
|
@@ -46,7 +49,7 @@ module RemoteExecutionHelper
|
|
|
46
49
|
hash_for_foreman_tasks_task_path(host_task)
|
|
47
50
|
.merge(:auth_object => host_task, :permission => :view_foreman_tasks)
|
|
48
51
|
)
|
|
49
|
-
end
|
|
52
|
+
end,
|
|
50
53
|
]
|
|
51
54
|
end
|
|
52
55
|
|
|
@@ -57,66 +60,63 @@ module RemoteExecutionHelper
|
|
|
57
60
|
def job_invocations_buttons
|
|
58
61
|
[
|
|
59
62
|
documentation_button_rex('3.2ExecutingaJob'),
|
|
60
|
-
new_link(_('Run Job'))
|
|
63
|
+
new_link(_('Run Job')),
|
|
61
64
|
]
|
|
62
65
|
end
|
|
63
66
|
|
|
64
|
-
# rubocop:disable Metrics/AbcSize
|
|
65
67
|
def job_invocation_task_buttons(task)
|
|
66
68
|
job_invocation = task.task_groups.find { |group| group.class == JobInvocationTaskGroup }.job_invocation
|
|
67
69
|
task_authorizer = Authorizer.new(User.current, :collection => [task])
|
|
68
70
|
buttons = []
|
|
69
71
|
if authorized_for(hash_for_new_job_invocation_path)
|
|
70
72
|
buttons << link_to(_('Rerun'), rerun_job_invocation_path(:id => job_invocation.id),
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
:class => 'btn btn-default',
|
|
74
|
+
:title => _('Rerun the job'))
|
|
73
75
|
end
|
|
74
76
|
if authorized_for(hash_for_new_job_invocation_path)
|
|
75
77
|
buttons << link_to(_('Rerun failed'), rerun_job_invocation_path(:id => job_invocation.id, :failed_only => 1),
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
:class => 'btn btn-default',
|
|
79
|
+
:disabled => job_invocation.failed_hosts.none?,
|
|
80
|
+
:title => _('Rerun on failed hosts'))
|
|
79
81
|
end
|
|
80
82
|
if authorized_for(:permission => :view_foreman_tasks, :auth_object => task, :authorizer => task_authorizer)
|
|
81
83
|
buttons << link_to(_('Job Task'), foreman_tasks_task_path(task),
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
:class => 'btn btn-default',
|
|
85
|
+
:title => _('See the last task details'))
|
|
84
86
|
end
|
|
85
87
|
if authorized_for(:permission => :cancel_job_invocations, :auth_object => job_invocation)
|
|
86
88
|
buttons << button_to(_('Cancel Job'), cancel_job_invocation_path(job_invocation),
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
:class => 'btn btn-danger',
|
|
90
|
+
:title => _('Try to cancel the job'),
|
|
91
|
+
:disabled => !task.cancellable?,
|
|
92
|
+
:method => :post)
|
|
91
93
|
buttons << button_to(_('Abort Job'), cancel_job_invocation_path(job_invocation, :force => true),
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
:class => 'btn btn-danger',
|
|
95
|
+
:title => _('Try to abort the job without waiting for the results from the remote hosts'),
|
|
96
|
+
:disabled => !task.cancellable?,
|
|
97
|
+
:method => :post)
|
|
96
98
|
end
|
|
97
99
|
return buttons
|
|
98
100
|
end
|
|
99
101
|
|
|
100
|
-
# rubocop:enable Metrics/AbcSize
|
|
101
|
-
|
|
102
102
|
def template_invocation_task_buttons(task, invocation)
|
|
103
103
|
buttons = []
|
|
104
104
|
if authorized_for(:permission => :view_foreman_tasks, :auth_object => task)
|
|
105
105
|
buttons << link_to(_('Task Details'), foreman_tasks_task_path(task),
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
:class => 'btn btn-default',
|
|
107
|
+
:title => _('See the task details'))
|
|
108
108
|
end
|
|
109
109
|
if authorized_for(:permission => :cancel_job_invocations, :auth_object => invocation)
|
|
110
110
|
buttons << link_to(_('Cancel Job'), cancel_foreman_tasks_task_path(task),
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
:class => 'btn btn-danger',
|
|
112
|
+
:title => _('Try to cancel the job on a host'),
|
|
113
|
+
:disabled => !task.cancellable?,
|
|
114
|
+
:method => :post)
|
|
115
115
|
buttons << link_to(_('Abort Job'), abort_foreman_tasks_task_path(task),
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
:class => 'btn btn-danger',
|
|
117
|
+
:title => _('Try to abort the job on a host without waiting for its result'),
|
|
118
|
+
:disabled => !task.cancellable?,
|
|
119
|
+
:method => :post)
|
|
120
120
|
end
|
|
121
121
|
buttons
|
|
122
122
|
end
|
|
@@ -128,7 +128,7 @@ module RemoteExecutionHelper
|
|
|
128
128
|
else
|
|
129
129
|
task_authorizer = Authorizer.new(User.current, :collection => [invocation.task])
|
|
130
130
|
link_to_if_authorized job_invocation_status(invocation),
|
|
131
|
-
|
|
131
|
+
hash_for_foreman_tasks_task_path(invocation.task).merge(:auth_object => invocation.task, :permission => :view_foreman_tasks, :authorizer => task_authorizer)
|
|
132
132
|
end
|
|
133
133
|
end
|
|
134
134
|
|
|
@@ -193,7 +193,7 @@ module RemoteExecutionHelper
|
|
|
193
193
|
_('N/A')
|
|
194
194
|
else
|
|
195
195
|
content_tag :span, (time > Time.now.utc ? _('in %s') : _('%s ago')) % time_ago_in_words(time),
|
|
196
|
-
|
|
196
|
+
{ :'data-original-title' => time.try(:in_time_zone), :rel => 'twipsy' }
|
|
197
197
|
end
|
|
198
198
|
end
|
|
199
199
|
|
|
@@ -205,23 +205,23 @@ module RemoteExecutionHelper
|
|
|
205
205
|
|
|
206
206
|
def description_checkbox_f(f, job_template, disabled)
|
|
207
207
|
check_box_tag('description_format_override',
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
208
|
+
job_template.generate_description_format,
|
|
209
|
+
f.object.description_format.nil?,
|
|
210
|
+
:class => 'description_format_override',
|
|
211
|
+
:name => f.object_name + '[description_override]',
|
|
212
|
+
:disabled => disabled,
|
|
213
|
+
:onchange => 'description_override(this);') + ' ' + _('Use default description template')
|
|
214
214
|
end
|
|
215
215
|
|
|
216
216
|
def description_format_textarea_f(f, job_template, disabled)
|
|
217
217
|
textarea_f f, 'description_format',
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
218
|
+
:label => _('Description template'),
|
|
219
|
+
:value => f.object.description_format || job_template.generate_description_format,
|
|
220
|
+
:rows => 2,
|
|
221
|
+
:onchange => 'regenerate_description(this);',
|
|
222
|
+
:class => 'description_format advanced',
|
|
223
|
+
:disabled => disabled,
|
|
224
|
+
:label_help => description_format_help
|
|
225
225
|
end
|
|
226
226
|
|
|
227
227
|
def description_format_help
|
|
@@ -234,6 +234,7 @@ module RemoteExecutionHelper
|
|
|
234
234
|
def load_template_from_task(template_invocation, target)
|
|
235
235
|
task = template_invocation.job_invocation.sub_task_for_host(target)
|
|
236
236
|
return if task.nil?
|
|
237
|
+
|
|
237
238
|
task.execution_plan.actions[1].try(:input).try(:[], 'script')
|
|
238
239
|
end
|
|
239
240
|
end
|