foreman-tasks 0.9.4 → 0.9.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a742bb53eee4218bb416d13f27591864e779bc34
4
- data.tar.gz: 3f229ddbcde5da4a71467ca6ae0c38fc8d54bab7
3
+ metadata.gz: 2fbc8738b9259442215b12e07307cb605dbdc299
4
+ data.tar.gz: e172529a5fd0c0950a163e403a8667dab0f8538c
5
5
  SHA512:
6
- metadata.gz: 3c686088b57ac3eecbd7e7baeb7ef16d78fb7053eeebc98921747c60a547d3cfaf477aa30c48272385d9eadfa30256fa649d830e609eb18291b9f30e56adaf95
7
- data.tar.gz: 699713e7bd48e5811d12cae6ff630ab77869cf0079f385defc106ba43851ebac14058f178c260ce5f81000ce4c1fe72132c2058c2af894f6cfd485ed3a2914f5
6
+ metadata.gz: 16557fbad3ca19db7cef81f6ee905ebcde440c5c397a85e2e5c77bdf1ed97a7984d8e9eb09610d257bb95202cd872241394cd1fcb45365e5bd2204648f8b434c
7
+ data.tar.gz: 898dba76fa6a6cb556555ea5fbc8403df8070ebe156b37410ada39a4bd58a853d1716f6eb1f4cfde4424e1ab6285086e75d519857db873b850cc4283ddd41586
@@ -36,6 +36,16 @@ module ForemanTasks
36
36
  redirect_to :back
37
37
  end
38
38
 
39
+ def abort
40
+ task = find_dynflow_task
41
+ if task.abort
42
+ flash[:notice] = _('Trying to abort the task')
43
+ else
44
+ flash[:warning] = _('The task cannot be aborted at the moment.')
45
+ end
46
+ redirect_to :back
47
+ end
48
+
39
49
  def resume
40
50
  task = find_dynflow_task
41
51
  if task.resumable?
@@ -86,7 +96,7 @@ module ForemanTasks
86
96
  case params[:action]
87
97
  when 'sub_tasks'
88
98
  :view
89
- when 'resume', 'unlock', 'force_unlock', 'cancel_step', 'cancel'
99
+ when 'resume', 'unlock', 'force_unlock', 'cancel_step', 'cancel', 'abort'
90
100
  :edit
91
101
  else
92
102
  super
@@ -31,6 +31,8 @@ module Actions
31
31
  # do nothing
32
32
  when ::Dynflow::Action::Cancellable::Cancel
33
33
  cancel_proxy_task
34
+ when ::Dynflow::Action::Cancellable::Abort
35
+ abort_proxy_task
34
36
  when CallbackData
35
37
  on_data(event.data)
36
38
  when ::Dynflow::Action::Timeouts::Timeout
@@ -78,6 +80,11 @@ module Actions
78
80
  end
79
81
  end
80
82
 
83
+ def abort_proxy_task
84
+ proxy.cancel_task(output[:proxy_task_id])
85
+ error! ForemanTasks::Task::TaskCancelledException.new(_('Task aborted: the task might be still running on the proxy'))
86
+ end
87
+
81
88
  def on_resume
82
89
  # TODO: add logic to load the data from the external action
83
90
  suspend
@@ -9,8 +9,8 @@ module ForemanTasks
9
9
  self.external_id = data[:id]
10
10
  self.started_at = utc_zone.parse(data[:started_at]) unless data[:started_at].nil?
11
11
  self.ended_at = utc_zone.parse(data[:ended_at]) unless data[:ended_at].nil?
12
+ self.result = map_result(data).to_s
12
13
  self.state = data[:state].to_s
13
- self.result = map_result(data[:result])
14
14
  self.start_at = utc_zone.parse(data[:start_at]) if data[:start_at]
15
15
  self.start_before = utc_zone.parse(data[:start_before]) if data[:start_before]
16
16
  self.parent_task_id ||= begin
@@ -32,6 +32,10 @@ module ForemanTasks
32
32
  execution_plan!.cancel.any?
33
33
  end
34
34
 
35
+ def abort
36
+ execution_plan!.cancel(true).any?
37
+ end
38
+
35
39
  def resumable?
36
40
  execution_plan.try(:state) == :paused
37
41
  end
@@ -148,9 +152,20 @@ module ForemanTasks
148
152
 
149
153
  private
150
154
 
151
- def map_result(result)
152
- result = :cancelled if result == :error && cancelled?
153
- result.to_s
155
+ def map_result(data)
156
+ if state_result_transitioned?(%w[planned pending], %w[stopped error], data) ||
157
+ (data[:result] == :error && cancelled?)
158
+ :cancelled
159
+ else
160
+ data[:result]
161
+ end
162
+ end
163
+
164
+ def state_result_transitioned?(from, to, data)
165
+ oldstate, oldresult = from
166
+ newstate, newresult = to
167
+ state == oldstate && data[:state].to_s == newstate &&
168
+ result == oldresult && data[:result].to_s == newresult
154
169
  end
155
170
 
156
171
  def cancelled?
data/config/routes.rb CHANGED
@@ -12,6 +12,7 @@ Foreman::Application.routes.draw do
12
12
  end
13
13
  member do
14
14
  get :sub_tasks
15
+ post :abort
15
16
  post :cancel
16
17
  post :resume
17
18
  post :unlock
@@ -29,7 +29,7 @@ same resource. It also optionally provides Dynflow infrastructure for using it f
29
29
  s.extra_rdoc_files = Dir['README*', 'LICENSE']
30
30
 
31
31
  s.add_dependency "foreman-tasks-core"
32
- s.add_dependency "dynflow", '~> 0.8.24'
32
+ s.add_dependency "dynflow", '~> 0.8.26'
33
33
  s.add_dependency "sequel" # for Dynflow process persistence
34
34
  s.add_dependency "sinatra" # for Dynflow web console
35
35
  s.add_dependency "daemons" # for running remote executor
@@ -58,7 +58,7 @@ module ForemanTasks
58
58
  security_block :foreman_tasks do |_map|
59
59
  permission :view_foreman_tasks, { :'foreman_tasks/tasks' => [:auto_complete_search, :sub_tasks, :index, :show],
60
60
  :'foreman_tasks/api/tasks' => [:bulk_search, :show, :index, :summary] }, :resource_type => ForemanTasks::Task.name
61
- permission :edit_foreman_tasks, { :'foreman_tasks/tasks' => [:resume, :unlock, :force_unlock, :cancel_step, :cancel],
61
+ permission :edit_foreman_tasks, { :'foreman_tasks/tasks' => [:resume, :unlock, :force_unlock, :cancel_step, :cancel, :abort],
62
62
  :'foreman_tasks/api/tasks' => [:bulk_resume] }, :resource_type => ForemanTasks::Task.name
63
63
 
64
64
  permission :create_recurring_logics, {}, :resource_type => ForemanTasks::RecurringLogic.name
@@ -1,3 +1,3 @@
1
1
  module ForemanTasks
2
- VERSION = '0.9.4'.freeze
2
+ VERSION = '0.9.5'.freeze
3
3
  end
@@ -0,0 +1,70 @@
1
+ require 'foreman_tasks_test_helper'
2
+ require 'foreman_tasks_core/otp_manager'
3
+
4
+ module ForemanTasksCore
5
+ class OtpManagerTest < ActiveSupport::TestCase
6
+ class TestOtpManager < OtpManager
7
+ def self.reset!
8
+ @passwords = nil
9
+ end
10
+ end
11
+
12
+ before do
13
+ TestOtpManager.reset!
14
+ end
15
+
16
+ let(:username) { 'myuser' }
17
+ let(:password) { '123456789' }
18
+ let(:base64) { 'bXl1c2VyOjEyMzQ1Njc4OQ==' }
19
+
20
+ it 'it doesn\'t raise when no passwords were generated yet' do
21
+ assert_nil TestOtpManager.drop_otp('missing', 'password')
22
+ end
23
+
24
+ it 'generates OTPs using SecureRandom.hex and converts them to strings' do
25
+ otp = 4
26
+ SecureRandom.stubs(:hex).returns(otp)
27
+ TestOtpManager.generate_otp(username).must_equal otp.to_s
28
+ end
29
+
30
+ it 'removes OTP only when correct username and password is provided' do
31
+ otp = TestOtpManager.generate_otp(username)
32
+ assert_nil TestOtpManager.drop_otp('wrong_username', 'wrong_password')
33
+ assert_nil TestOtpManager.drop_otp(username, 'wrong_password')
34
+ assert_nil TestOtpManager.drop_otp('wrong_username', otp)
35
+ TestOtpManager.drop_otp(username, otp).must_equal otp
36
+ end
37
+
38
+ it 'parses the hash correctly' do
39
+ SecureRandom.stubs(:hex).returns(password)
40
+ TestOtpManager.expects(:drop_otp).with(username, password.to_s)
41
+ TestOtpManager.authenticate(base64)
42
+ end
43
+
44
+ it 'authenticates correctly' do
45
+ SecureRandom.stubs(:hex).returns(password)
46
+ generated = TestOtpManager.generate_otp(username)
47
+
48
+ TestOtpManager.authenticate(base64).must_equal generated
49
+ end
50
+
51
+ it 'OTPs can be used only once' do
52
+ SecureRandom.stubs(:hex).returns(password)
53
+ generated = TestOtpManager.generate_otp(username)
54
+
55
+ TestOtpManager.authenticate(base64).must_equal generated
56
+ assert_nil TestOtpManager.authenticate(base64)
57
+ end
58
+
59
+ it 'creates token from username and password correctly' do
60
+ TestOtpManager.tokenize(username, password).must_equal base64
61
+ end
62
+
63
+ it 'overwrites old OTP when generating a new one for the same username' do
64
+ old = TestOtpManager.generate_otp(username)
65
+ new = TestOtpManager.generate_otp(username)
66
+ assert_nil TestOtpManager.drop_otp(username, old)
67
+ TestOtpManager.drop_otp(username, new).must_equal new
68
+ end
69
+ end
70
+ 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: 0.9.4
4
+ version: 0.9.5
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: 2017-07-11 00:00:00.000000000 Z
11
+ date: 2017-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: foreman-tasks-core
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.8.24
33
+ version: 0.8.26
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.8.24
40
+ version: 0.8.26
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: sequel
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -261,6 +261,7 @@ files:
261
261
  - test/unit/config/environment.rb
262
262
  - test/unit/daemon_test.rb
263
263
  - test/unit/dynflow_console_authorizer_test.rb
264
+ - test/unit/otp_manager_test.rb
264
265
  - test/unit/proxy_selector_test.rb
265
266
  - test/unit/recurring_logic_test.rb
266
267
  - test/unit/task_groups_test.rb
@@ -305,6 +306,7 @@ test_files:
305
306
  - test/unit/config/environment.rb
306
307
  - test/unit/daemon_test.rb
307
308
  - test/unit/dynflow_console_authorizer_test.rb
309
+ - test/unit/otp_manager_test.rb
308
310
  - test/unit/proxy_selector_test.rb
309
311
  - test/unit/recurring_logic_test.rb
310
312
  - test/unit/task_groups_test.rb