foreman-tasks 5.1.1 → 5.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/.rubocop.yml +0 -4
- data/.rubocop_todo.yml +0 -2
- data/README.md +8 -6
- data/app/graphql/mutations/recurring_logics/cancel.rb +27 -0
- data/app/graphql/types/recurring_logic.rb +2 -0
- data/app/lib/actions/proxy_action.rb +2 -12
- data/app/models/foreman_tasks/remote_task.rb +3 -19
- data/app/views/foreman_tasks/task_groups/recurring_logic_task_groups/_recurring_logic_task_group.html.erb +4 -0
- data/extra/foreman-tasks-export.sh +7 -3
- data/foreman-tasks.gemspec +1 -3
- data/lib/foreman_tasks/engine.rb +2 -0
- data/lib/foreman_tasks/tasks/export_tasks.rake +24 -4
- data/lib/foreman_tasks/version.rb +1 -1
- data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/package.json +7 -9
- data/test/controllers/api/tasks_controller_test.rb +1 -1
- data/test/factories/recurring_logic_factory.rb +7 -1
- data/test/graphql/mutations/recurring_logics/cancel_mutation_test.rb +66 -0
- data/test/support/dummy_proxy_action.rb +6 -0
- data/test/unit/actions/proxy_action_test.rb +11 -11
- data/test/unit/remote_task_test.rb +0 -8
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa2189368cc093a6ca613ca1b91add99bc3689b2cb22cd0c04a3718821b5f27f
|
4
|
+
data.tar.gz: f7e82294bbbb76fe6576b6c2de9e55c16342962f711a8e5c9070787be304a87c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f20e5fba4dbc2401a4fed1f5eb68961ccc7095071fc309316ad14392b9209141e96aa2372eb7bb5db0e7f829ef08727ff2e232e53de86baa8385183ddb722252
|
7
|
+
data.tar.gz: 534ac74d1c8010ac25330562a6bdb713beacc413d2c681ee72f865727741cfb17e04d9dda2c0ea8ab7bde2f7f2e08f54fa4266e25686ca9d1f38c5309b24b94c
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
@@ -11,7 +11,6 @@
|
|
11
11
|
# Include: **/*.gemspec
|
12
12
|
Gemspec/RequiredRubyVersion:
|
13
13
|
Exclude:
|
14
|
-
- 'foreman-tasks-core.gemspec'
|
15
14
|
- 'foreman-tasks.gemspec'
|
16
15
|
|
17
16
|
# Offense count: 1
|
@@ -37,7 +36,6 @@ Naming/MemoizedInstanceVariableName:
|
|
37
36
|
Exclude:
|
38
37
|
- 'app/controllers/foreman_tasks/recurring_logics_controller.rb'
|
39
38
|
- 'app/lib/actions/recurring_action.rb'
|
40
|
-
- 'lib/foreman_tasks_core/otp_manager.rb'
|
41
39
|
|
42
40
|
# Offense count: 11
|
43
41
|
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
|
data/README.md
CHANGED
@@ -6,7 +6,8 @@ happening/happened in your Foreman instance. A framework for asynchronous tasks
|
|
6
6
|
|
7
7
|
* Website: [TheForeman.org](http://theforeman.org)
|
8
8
|
* ServerFault tag: [Foreman](http://serverfault.com/questions/tagged/foreman)
|
9
|
-
* Issues: [
|
9
|
+
* Issues: [Foreman-tasks Redmine](http://projects.theforeman.org/projects/foreman-tasks)
|
10
|
+
* Manual: [Foreman-tasks Manual](https://www.theforeman.org/plugins/foreman_tasks/0.8/index.html)
|
10
11
|
* Wiki: [Foreman wiki](http://projects.theforeman.org/projects/foreman/wiki/About)
|
11
12
|
* Community and support: #theforeman for general support, #theforeman-dev for development chat in [Freenode](irc.freenode.net)
|
12
13
|
* Mailing lists:
|
@@ -25,6 +26,7 @@ happening/happened in your Foreman instance. A framework for asynchronous tasks
|
|
25
26
|
| >= 1.22 | ~> 0.15.0 |
|
26
27
|
| >= 2.0 | ~> 1.0.0 |
|
27
28
|
| >= 2.1 | ~> 2.0.0 |
|
29
|
+
| >= 2.6 | ~> 5.2.0 |
|
28
30
|
|
29
31
|
Installation
|
30
32
|
------------
|
@@ -154,9 +156,9 @@ rails root directory. See `-h` for more details and options
|
|
154
156
|
Tasks cleanup
|
155
157
|
-------------
|
156
158
|
|
157
|
-
Although
|
158
|
-
tasks can
|
159
|
-
|
159
|
+
Although the history of tasks has an auditing value, some kinds of
|
160
|
+
tasks can rapidly increase. Therefore, there is a mechanism for
|
161
|
+
cleaning up the tasks using a rake command. When running without
|
160
162
|
any arguments, the tasks are deleted based on the default parameters
|
161
163
|
defined in the code.
|
162
164
|
|
@@ -179,7 +181,7 @@ override the default configuration inside the configuration
|
|
179
181
|
```
|
180
182
|
:foreman-tasks:
|
181
183
|
:cleanup:
|
182
|
-
# the period after
|
184
|
+
# the period after which to delete all the tasks (by default, all tasks are not deleted after some period)
|
183
185
|
:after: 365d
|
184
186
|
# per action settings to override the default defined in the actions (cleanup_after method)
|
185
187
|
:actions:
|
@@ -194,7 +196,7 @@ to specify the search criteria for the cleanup manually:
|
|
194
196
|
* `TASK_SEARCH`: scoped search filter (example: 'label =
|
195
197
|
"Actions::Foreman::Host::ImportFacts"')
|
196
198
|
* `AFTER`: delete tasks created after `AFTER` period. Expected format
|
197
|
-
is a number followed by the time unit (`s`, `h`, `m`, `y`), such as
|
199
|
+
is a number followed by the time unit (`s`, `h`, `d`, `m`, `y`), such as
|
198
200
|
`10d` for 10 days (applicable only when the `TASK_SEARCH` option is
|
199
201
|
specified)
|
200
202
|
* `STATES`: comma separated list of task states to touch with the
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Mutations
|
2
|
+
module RecurringLogics
|
3
|
+
class Cancel < BaseMutation
|
4
|
+
graphql_name 'CancelRecurringLogic'
|
5
|
+
description 'Cancels recurring logic and all its active tasks'
|
6
|
+
resource_class ::ForemanTasks::RecurringLogic
|
7
|
+
|
8
|
+
argument :id, ID, required: true
|
9
|
+
|
10
|
+
field :errors, [Types::AttributeError], null: false
|
11
|
+
field :recurring_logic, Types::RecurringLogic, null: true
|
12
|
+
|
13
|
+
def resolve(id:)
|
14
|
+
recurring_logic = load_object_by(id: id)
|
15
|
+
authorize!(recurring_logic, :edit)
|
16
|
+
task_errors = []
|
17
|
+
begin
|
18
|
+
recurring_logic.cancel
|
19
|
+
rescue => e
|
20
|
+
task_errors = [{ path: ['tasks'], message: "There has been an error when canceling one of the tasks: #{e}" }]
|
21
|
+
end
|
22
|
+
errors = recurring_logic.errors.any? ? map_errors_to_path(recurring_logic) : []
|
23
|
+
{ recurring_logic: recurring_logic, errors: (errors + task_errors) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -29,10 +29,10 @@ module Actions
|
|
29
29
|
default_connection_options.each do |key, value|
|
30
30
|
options[:connection_options][key] = value unless options[:connection_options].key?(key)
|
31
31
|
end
|
32
|
-
plan_self(options.merge(:proxy_url => proxy.url, :proxy_action_name => klass.to_s
|
32
|
+
plan_self(options.merge(:proxy_url => proxy.url, :proxy_action_name => klass.to_s))
|
33
33
|
# Just saving the RemoteTask is enough when using batch triggering
|
34
34
|
# It will be picked up by the ProxyBatchTriggering middleware
|
35
|
-
if input[:use_batch_triggering] &&
|
35
|
+
if input[:use_batch_triggering] && input.dig(:connection_options, :proxy_batch_triggering)
|
36
36
|
prepare_remote_task.save!
|
37
37
|
end
|
38
38
|
end
|
@@ -193,11 +193,6 @@ module Actions
|
|
193
193
|
:proxy_batch_triggering => Setting['foreman_tasks_proxy_batch_trigger'] || false }
|
194
194
|
end
|
195
195
|
|
196
|
-
def with_batch_triggering?(proxy_version)
|
197
|
-
((proxy_version[:major] == 1 && proxy_version[:minor] > 20) || proxy_version[:major] > 1) &&
|
198
|
-
input.fetch(:connection_options, {}).fetch(:proxy_batch_triggering, false)
|
199
|
-
end
|
200
|
-
|
201
196
|
def clean_remote_task(*_args)
|
202
197
|
remote_task.destroy! if remote_task
|
203
198
|
end
|
@@ -222,11 +217,6 @@ module Actions
|
|
222
217
|
.try(:fetch, 'output', {}) || {}
|
223
218
|
end
|
224
219
|
|
225
|
-
def proxy_version(proxy)
|
226
|
-
match = proxy.statuses[:version].version['version'].match(/(\d+)\.(\d+)\.(\d+)/)
|
227
|
-
{ :major => match[1].to_i, :minor => match[2].to_i, :patch => match[3].to_i }
|
228
|
-
end
|
229
|
-
|
230
220
|
def failed_proxy_tasks
|
231
221
|
metadata[:failed_proxy_tasks] ||= []
|
232
222
|
end
|
@@ -16,7 +16,7 @@ module ForemanTasks
|
|
16
16
|
# Triggers a task on the proxy "the old way"
|
17
17
|
def trigger(proxy_action_name, input)
|
18
18
|
response = begin
|
19
|
-
proxy.
|
19
|
+
proxy.launch_tasks('single', :action_class => proxy_action_name, :action_input => input)
|
20
20
|
rescue RestClient::Exception => e
|
21
21
|
logger.warn "Could not trigger task on the smart proxy: #{e.message}"
|
22
22
|
{}
|
@@ -31,28 +31,12 @@ module ForemanTasks
|
|
31
31
|
acc.merge(remote_task.execution_plan_id => { :action_input => remote_task.proxy_input,
|
32
32
|
:action_class => remote_task.proxy_action_name })
|
33
33
|
end
|
34
|
-
|
34
|
+
results = remote_tasks.first.proxy.launch_tasks(operation, input_hash)
|
35
|
+
remote_tasks.each { |remote_task| remote_task.update_from_batch_trigger results[remote_task.execution_plan_id] }
|
35
36
|
end
|
36
37
|
remote_tasks
|
37
38
|
end
|
38
39
|
|
39
|
-
# Attempt to trigger the tasks using the new API and fall back to the old one
|
40
|
-
# if it fails
|
41
|
-
def self.safe_batch_trigger(operation, remote_tasks, input_hash)
|
42
|
-
results = remote_tasks.first.proxy.launch_tasks(operation, input_hash)
|
43
|
-
remote_tasks.each { |remote_task| remote_task.update_from_batch_trigger results[remote_task.execution_plan_id] }
|
44
|
-
rescue RestClient::NotFound
|
45
|
-
fallback_batch_trigger remote_tasks, input_hash
|
46
|
-
end
|
47
|
-
|
48
|
-
# Trigger the tasks one-by-one using the old API
|
49
|
-
def self.fallback_batch_trigger(remote_tasks, input_hash)
|
50
|
-
remote_tasks.each do |remote_task|
|
51
|
-
task_data = input_hash[remote_task.execution_plan_id]
|
52
|
-
remote_task.trigger(task_data[:action_class], task_data[:action_input])
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
40
|
def update_from_batch_trigger(data)
|
57
41
|
if data['result'] == 'success'
|
58
42
|
self.remote_task_id = data['task_id']
|
@@ -40,4 +40,8 @@
|
|
40
40
|
<th><%= N_("Purpose") %></th>
|
41
41
|
<td><%= recurring_logic.purpose %></td>
|
42
42
|
</tr>
|
43
|
+
<tr>
|
44
|
+
<th><%= N_("Task count") %></th>
|
45
|
+
<td><%= link_to(task_group.tasks.count, foreman_tasks_tasks_url(:search => "task_group.id = #{task_group.id}")) %></td>
|
46
|
+
</tr>
|
43
47
|
</table>
|
@@ -14,7 +14,7 @@ function die() {
|
|
14
14
|
function build_rake() {
|
15
15
|
echo -n "$RAKE_COMMAND "
|
16
16
|
echo -n 'foreman_tasks:export_tasks '
|
17
|
-
for env in TASK_SEARCH TASK_FILE TASK_FORMAT TASK_DAYS; do
|
17
|
+
for env in TASK_SEARCH TASK_FILE TASK_FORMAT TASK_DAYS SKIP_FAILED; do
|
18
18
|
local value="${!env}"
|
19
19
|
[ -n "${value}" ] && echo -n "${env}=$(printf '%q' "$value") "
|
20
20
|
done
|
@@ -46,11 +46,12 @@ EOF
|
|
46
46
|
-f|--format FORMAT & export tasks in FORMAT, one of html, html-dir, csv
|
47
47
|
-o|--output FILE & export tasks into FILE, a random file will be used if not provided
|
48
48
|
-s|--search QUERY & use QUERY in scoped search format to match tasks to export
|
49
|
+
-S|--skip-failed & skip tasks that fail to export
|
49
50
|
EOF
|
50
51
|
}
|
51
52
|
|
52
|
-
SHORTOPTS="d:Ehs:o:f:"
|
53
|
-
LONGOPTS="days:,execute,help,search:,output:,format
|
53
|
+
SHORTOPTS="d:Ehs:o:f:S"
|
54
|
+
LONGOPTS="days:,execute,help,search:,output:,format:,skip-failed"
|
54
55
|
|
55
56
|
ARGS=$(getopt -s bash \
|
56
57
|
--options $SHORTOPTS \
|
@@ -96,6 +97,9 @@ while true; do
|
|
96
97
|
-E|--execute)
|
97
98
|
EXECUTE=1
|
98
99
|
;;
|
100
|
+
-S|--skip-failed)
|
101
|
+
SKIP_FAILED=1
|
102
|
+
;;
|
99
103
|
\?)
|
100
104
|
die 1 "Invalid option: -$OPTARG"
|
101
105
|
;;
|
data/foreman-tasks.gemspec
CHANGED
@@ -20,9 +20,7 @@ same resource. It also optionally provides Dynflow infrastructure for using it f
|
|
20
20
|
DESC
|
21
21
|
|
22
22
|
s.files = `git ls-files`.split("\n").reject do |file|
|
23
|
-
file.end_with?("test.rake")
|
24
|
-
file.start_with?('lib/foreman_tasks_core') ||
|
25
|
-
file == 'foreman-tasks-core.gemspec'
|
23
|
+
file.end_with?("test.rake")
|
26
24
|
end
|
27
25
|
|
28
26
|
s.test_files = `git ls-files test`.split("\n")
|
data/lib/foreman_tasks/engine.rb
CHANGED
@@ -70,6 +70,8 @@ module ForemanTasks
|
|
70
70
|
register_graphql_query_field :recurring_logic, '::Types::RecurringLogic', :record_field
|
71
71
|
register_graphql_query_field :recurring_logics, '::Types::RecurringLogic', :collection_field
|
72
72
|
|
73
|
+
register_graphql_mutation_field :cancel_recurring_logic, ::Mutations::RecurringLogics::Cancel
|
74
|
+
|
73
75
|
logger :dynflow, :enabled => true
|
74
76
|
logger :action, :enabled => true
|
75
77
|
|
@@ -14,6 +14,7 @@ namespace :foreman_tasks do
|
|
14
14
|
* TASK_FILE : file to export to
|
15
15
|
* TASK_FORMAT : format to use for the export (either html, html-dir or csv)
|
16
16
|
* TASK_DAYS : number of days to go back
|
17
|
+
* SKIP_FAILED : skip tasks that fail to export (true or false[default])
|
17
18
|
|
18
19
|
If TASK_SEARCH is not defined, it defaults to all tasks in the past 7 days and
|
19
20
|
all unsuccessful tasks in the past 60 days. The default TASK_FORMAT is html
|
@@ -244,8 +245,10 @@ namespace :foreman_tasks do
|
|
244
245
|
CSV.open(export_filename, 'wb') do |csv|
|
245
246
|
csv << %w[id state type label result parent_task_id started_at ended_at duration]
|
246
247
|
tasks.find_each do |task|
|
247
|
-
|
248
|
-
|
248
|
+
with_error_handling(task) do
|
249
|
+
csv << [task.id, task.state, task.type, task.label, task.result,
|
250
|
+
task.parent_task_id, task.started_at, task.ended_at, task.duration]
|
251
|
+
end
|
249
252
|
end
|
250
253
|
end
|
251
254
|
end
|
@@ -261,8 +264,11 @@ namespace :foreman_tasks do
|
|
261
264
|
PageHelper.pagify(index) do |io|
|
262
265
|
PageHelper.generate_with_index(io) do |index|
|
263
266
|
tasks.find_each.each_with_index do |task, count|
|
264
|
-
|
265
|
-
|
267
|
+
content = with_error_handling(task) { renderer.render_task(task) }
|
268
|
+
if content
|
269
|
+
File.open(File.join(workdir, "#{task.id}.html"), 'w') { |file| PageHelper.pagify(file, content) }
|
270
|
+
with_error_handling(task, _('task index entry')) { PageHelper.generate_index_entry(index, task) }
|
271
|
+
end
|
266
272
|
puts "#{count + 1}/#{total}"
|
267
273
|
end
|
268
274
|
end
|
@@ -282,6 +288,20 @@ namespace :foreman_tasks do
|
|
282
288
|
end
|
283
289
|
end
|
284
290
|
|
291
|
+
def with_error_handling(task, what = _('task'))
|
292
|
+
yield
|
293
|
+
rescue StandardError => e
|
294
|
+
resolution = SKIP_ERRORS ? _(', skipping') : ''
|
295
|
+
puts _("WARNING: %{what} failed to export%{resolution}. Additional task details below.") % { :what => what, :resolution => resolution }
|
296
|
+
puts task.inspect
|
297
|
+
unless SKIP_ERRORS
|
298
|
+
puts _("Re-run with SKIP_FAILED=true if you want to simply skip any tasks that fail to export.")
|
299
|
+
raise e
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
SKIP_ERRORS = ['true', '1', 'y', 'yes'].include? ENV['SKIP_FAILED'].downcase
|
304
|
+
|
285
305
|
filter = if ENV['TASK_SEARCH'].nil? && ENV['TASK_DAYS'].nil?
|
286
306
|
"started_at > \"#{7.days.ago.to_s(:db)}\" || " \
|
287
307
|
"(result != success && started_at > \"#{60.days.ago.to_s(:db)})\""
|
Binary file
|
Binary file
|
Binary file
|
data/package.json
CHANGED
@@ -23,20 +23,18 @@
|
|
23
23
|
"url": "http://projects.theforeman.org/projects/foreman-tasks/issues"
|
24
24
|
},
|
25
25
|
"peerDependencies": {
|
26
|
-
"@theforeman/vendor": "
|
26
|
+
"@theforeman/vendor": "^8.15.0"
|
27
27
|
},
|
28
28
|
"dependencies": {
|
29
|
-
"c3": "^0.4.11"
|
30
|
-
"humanize-duration": "^3.20.1",
|
31
|
-
"react-intl": "^2.8.0"
|
29
|
+
"c3": "^0.4.11"
|
32
30
|
},
|
33
31
|
"devDependencies": {
|
34
32
|
"@babel/core": "^7.7.0",
|
35
|
-
"@theforeman/builder": "^
|
36
|
-
"@theforeman/eslint-plugin-foreman": "
|
37
|
-
"@theforeman/stories": "^
|
38
|
-
"@theforeman/test": "^
|
39
|
-
"@theforeman/vendor-dev": "^
|
33
|
+
"@theforeman/builder": "^8.15.0",
|
34
|
+
"@theforeman/eslint-plugin-foreman": "^8.15.0",
|
35
|
+
"@theforeman/stories": "^8.15.0",
|
36
|
+
"@theforeman/test": "^8.15.0",
|
37
|
+
"@theforeman/vendor-dev": "^8.15.0",
|
40
38
|
"babel-eslint": "^10.0.3",
|
41
39
|
"eslint": "^6.7.2",
|
42
40
|
"jed": "^1.1.1",
|
@@ -192,7 +192,7 @@ module ForemanTasks
|
|
192
192
|
_(task.state).must_equal 'running'
|
193
193
|
_(task.result).must_equal 'pending'
|
194
194
|
|
195
|
-
callback = Support::DummyProxyAction.proxy.log[:trigger_task].first[1][:callback]
|
195
|
+
callback = Support::DummyProxyAction.proxy.log[:trigger_task].first[1][:action_input][:callback]
|
196
196
|
post :callback, params: { 'callback' => callback, 'data' => { 'result' => 'success' } }
|
197
197
|
triggered.finished.wait(5)
|
198
198
|
|
@@ -1,8 +1,14 @@
|
|
1
1
|
FactoryBot.define do
|
2
2
|
factory :recurring_logic, :class => ForemanTasks::RecurringLogic do
|
3
3
|
cron_line { '* * * * *' }
|
4
|
-
|
4
|
+
association :task_group
|
5
5
|
end
|
6
6
|
|
7
|
+
factory :task_group, :class => ::ForemanTasks::TaskGroup do
|
8
|
+
type { "ForemanTasks::TaskGroups::RecurringLogicTaskGroup" }
|
9
|
+
end
|
7
10
|
factory :recurring_logic_task_group, :class => ::ForemanTasks::TaskGroups::RecurringLogicTaskGroup
|
11
|
+
factory :task_group_member, :class => ::ForemanTasks::TaskGroupMember do
|
12
|
+
association :task_group, :task
|
13
|
+
end
|
8
14
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'foreman_tasks_test_helper'
|
2
|
+
|
3
|
+
module Mutations
|
4
|
+
module RecurringLogics
|
5
|
+
class CancelMutationTest < ActiveSupport::TestCase
|
6
|
+
setup do
|
7
|
+
@task = FactoryBot.create(:dynflow_task, state: 'pending')
|
8
|
+
@task_group = FactoryBot.create(:recurring_logic_task_group)
|
9
|
+
@task_group_member = FactoryBot.create(:task_group_member, task: @task, task_group: @task_group)
|
10
|
+
@recurring_logic = FactoryBot.create(:recurring_logic, task_group: @task_group)
|
11
|
+
@id = Foreman::GlobalId.for(@recurring_logic)
|
12
|
+
@variables = { id: @id }
|
13
|
+
@query =
|
14
|
+
<<-GRAPHQL
|
15
|
+
mutation CancelRecurringLogic($id:ID!) {
|
16
|
+
cancelRecurringLogic(input: { id: $id }){
|
17
|
+
recurringLogic {
|
18
|
+
id
|
19
|
+
state
|
20
|
+
cronLine
|
21
|
+
}
|
22
|
+
errors {
|
23
|
+
message
|
24
|
+
path
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
GRAPHQL
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'as admin' do
|
32
|
+
setup do
|
33
|
+
@context = { current_user: FactoryBot.create(:user, :admin) }
|
34
|
+
end
|
35
|
+
|
36
|
+
test 'should cancel recurring logic' do
|
37
|
+
assert_not_equal 'cancelled', @recurring_logic.state
|
38
|
+
result = ForemanGraphqlSchema.execute(@query, variables: @variables, context: @context)
|
39
|
+
assert_empty result['errors']
|
40
|
+
assert_empty result['data']['cancelRecurringLogic']['errors']
|
41
|
+
assert_equal 'cancelled', result['data']['cancelRecurringLogic']['recurringLogic']['state']
|
42
|
+
@recurring_logic.reload
|
43
|
+
assert_equal 'cancelled', @recurring_logic.state
|
44
|
+
end
|
45
|
+
|
46
|
+
test 'should handle errors on execution plan load failure' do
|
47
|
+
invalid_plan = ::Dynflow::ExecutionPlan::InvalidPlan.new(StandardError.new('This is a failure'), 'xyz', 'test-label', 'invalid')
|
48
|
+
::Dynflow::Persistence.any_instance.stubs(:load_execution_plan).returns(invalid_plan)
|
49
|
+
result = ForemanGraphqlSchema.execute(@query, variables: @variables, context: @context)
|
50
|
+
assert_equal "There has been an error when canceling one of the tasks: This is a failure", result['data']['cancelRecurringLogic']['errors'].first['message']
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'as viewer' do
|
55
|
+
setup do
|
56
|
+
@context = { current_user: setup_user('view', 'recurring_logics') }
|
57
|
+
end
|
58
|
+
|
59
|
+
test 'should not allow to cancel recurring logic' do
|
60
|
+
result = ForemanGraphqlSchema.execute(@query, variables: @variables, context: @context)
|
61
|
+
assert_includes result['errors'].first['message'], 'Unauthorized.'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -36,6 +36,12 @@ module Support
|
|
36
36
|
def statuses
|
37
37
|
{ version: DummyProxyVersion.new('1.21.0') }
|
38
38
|
end
|
39
|
+
|
40
|
+
def launch_tasks(operation, args = {})
|
41
|
+
@log[:trigger_task] << [operation, args]
|
42
|
+
@task_triggered.fulfill(true)
|
43
|
+
{ 'task_id' => @uuid, 'result' => 'success' }
|
44
|
+
end
|
39
45
|
end
|
40
46
|
|
41
47
|
class ProxySelector < ::ForemanTasks::ProxySelector
|
@@ -11,12 +11,11 @@ module ForemanTasks
|
|
11
11
|
let(:batch_triggering) { false }
|
12
12
|
|
13
13
|
before do
|
14
|
-
Support::DummyProxyAction.any_instance.stubs(:with_batch_triggering?).returns(batch_triggering)
|
15
14
|
Support::DummyProxyAction.reset
|
16
15
|
RemoteTask.any_instance.stubs(:proxy).returns(Support::DummyProxyAction.proxy)
|
17
16
|
Setting.stubs(:[]).with('foreman_tasks_proxy_action_retry_interval')
|
18
17
|
Setting.stubs(:[]).with('foreman_tasks_proxy_action_retry_count')
|
19
|
-
Setting.stubs(:[]).with('foreman_tasks_proxy_batch_trigger')
|
18
|
+
Setting.stubs(:[]).with('foreman_tasks_proxy_batch_trigger').returns(batch_triggering)
|
20
19
|
@action = create_and_plan_action(Support::DummyProxyAction,
|
21
20
|
Support::DummyProxyAction.proxy,
|
22
21
|
'Proxy::DummyAction',
|
@@ -29,17 +28,18 @@ module ForemanTasks
|
|
29
28
|
describe 'first run' do
|
30
29
|
it 'triggers the corresponding action on the proxy' do
|
31
30
|
proxy_call = Support::DummyProxyAction.proxy.log[:trigger_task].first
|
32
|
-
expected_call = ['
|
33
|
-
{
|
34
|
-
|
35
|
-
'
|
31
|
+
expected_call = ['single',
|
32
|
+
{ :action_class => 'Proxy::DummyAction',
|
33
|
+
:action_input =>
|
34
|
+
{ 'foo' => 'bar',
|
35
|
+
'secrets' => secrets,
|
36
|
+
'connection_options' =>
|
36
37
|
{ 'retry_interval' => 15, 'retry_count' => 4,
|
37
38
|
'proxy_batch_triggering' => batch_triggering },
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
'callback' => { 'task_id' => Support::DummyProxyAction.proxy.uuid, 'step_id' => @action.run_step_id } }]
|
39
|
+
'use_batch_triggering' => batch_triggering,
|
40
|
+
'proxy_url' => 'proxy.example.com',
|
41
|
+
'proxy_action_name' => 'Proxy::DummyAction',
|
42
|
+
'callback' => { 'task_id' => Support::DummyProxyAction.proxy.uuid, 'step_id' => @action.run_step_id } } }]
|
43
43
|
_(proxy_call).must_equal(expected_call)
|
44
44
|
end
|
45
45
|
|
@@ -28,14 +28,6 @@ module ForemanTasks
|
|
28
28
|
_(remote_task.remote_task_id).must_equal((remote_task.id + 5).to_s)
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
32
|
-
it 'fallbacks to old way when batch trigger gets 404' do
|
33
|
-
fake_proxy = mock
|
34
|
-
fake_proxy.expects(:launch_tasks).raises(RestClient::NotFound.new)
|
35
|
-
remote_tasks.first.expects(:proxy).returns(fake_proxy)
|
36
|
-
remote_tasks.each { |task| task.expects(:trigger) }
|
37
|
-
RemoteTask.batch_trigger('a_operation', remote_tasks)
|
38
|
-
end
|
39
31
|
end
|
40
32
|
end
|
41
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman-tasks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Nečas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dynflow
|
@@ -133,6 +133,7 @@ files:
|
|
133
133
|
- app/controllers/foreman_tasks/react_controller.rb
|
134
134
|
- app/controllers/foreman_tasks/recurring_logics_controller.rb
|
135
135
|
- app/controllers/foreman_tasks/tasks_controller.rb
|
136
|
+
- app/graphql/mutations/recurring_logics/cancel.rb
|
136
137
|
- app/graphql/types/recurring_logic.rb
|
137
138
|
- app/graphql/types/task.rb
|
138
139
|
- app/graphql/types/triggering.rb
|
@@ -304,6 +305,7 @@ files:
|
|
304
305
|
- test/factories/task_factory.rb
|
305
306
|
- test/factories/triggering_factory.rb
|
306
307
|
- test/foreman_tasks_test_helper.rb
|
308
|
+
- test/graphql/mutations/recurring_logics/cancel_mutation_test.rb
|
307
309
|
- test/graphql/queries/recurring_logic_test.rb
|
308
310
|
- test/graphql/queries/recurring_logics_query_test.rb
|
309
311
|
- test/graphql/queries/task_query_test.rb
|
@@ -618,6 +620,7 @@ test_files:
|
|
618
620
|
- test/factories/task_factory.rb
|
619
621
|
- test/factories/triggering_factory.rb
|
620
622
|
- test/foreman_tasks_test_helper.rb
|
623
|
+
- test/graphql/mutations/recurring_logics/cancel_mutation_test.rb
|
621
624
|
- test/graphql/queries/recurring_logic_test.rb
|
622
625
|
- test/graphql/queries/recurring_logics_query_test.rb
|
623
626
|
- test/graphql/queries/task_query_test.rb
|