foreman-tasks 0.14.0 → 0.14.1
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 +5 -5
- data/README.md +1 -0
- data/app/controllers/foreman_tasks/tasks_controller.rb +7 -5
- data/app/lib/actions/action_with_sub_plans.rb +0 -2
- data/app/lib/actions/foreman/host/import_facts.rb +7 -3
- data/app/lib/actions/middleware/watch_delegated_proxy_sub_tasks.rb +2 -2
- data/app/models/foreman_tasks/task.rb +34 -11
- data/app/models/setting/foreman_tasks.rb +1 -0
- data/foreman-tasks.gemspec +1 -1
- data/lib/foreman_tasks.rb +9 -2
- data/lib/foreman_tasks/engine.rb +5 -1
- data/lib/foreman_tasks/version.rb +1 -1
- data/test/controllers/tasks_controller_test.rb +8 -0
- data/test/unit/task_test.rb +18 -0
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fddcfe8ab9f1550261511074f70d3391836126c7fe54839857f0c10c31d2d456
|
4
|
+
data.tar.gz: ac4bf4b19d05f6d6af13440655d76fce521ec76a7bdae32207a1ed883cfaa569
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d6e2483dfdf63d5b32980889edd41af2d496ba5fce667593887f678781587282c17fb9abf3e77e22750d4c965c7930e45608c9a4ec7fa475d6c8f0b8e3a69e6
|
7
|
+
data.tar.gz: 5345f2fdce7081763d79468b548add5eea06093ec43581efbc3a84614571477d7446faaf4d10bda41b5c3007f0c0e3a207ab9d0d403ece7872aa2ee7ca2825a3
|
data/README.md
CHANGED
@@ -11,13 +11,14 @@ module ForemanTasks
|
|
11
11
|
|
12
12
|
def index
|
13
13
|
params[:order] ||= 'started_at DESC'
|
14
|
-
@tasks = filter(resource_base)
|
15
14
|
respond_to do |format|
|
16
15
|
format.html do
|
16
|
+
@tasks = filter(resource_base)
|
17
17
|
render :index
|
18
18
|
end
|
19
19
|
format.csv do
|
20
|
-
|
20
|
+
@tasks = filter(resource_base, paginate: false)
|
21
|
+
csv_response(@tasks, [:action, :state, :result, 'started_at.in_time_zone', 'ended_at.in_time_zone', :username], ['Action', 'State', 'Result', 'Started At', 'Ended At', 'User'])
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -124,11 +125,12 @@ module ForemanTasks
|
|
124
125
|
resource_scope.where(:type => 'ForemanTasks::Task::DynflowTask').find(params[:id])
|
125
126
|
end
|
126
127
|
|
127
|
-
def filter(scope)
|
128
|
+
def filter(scope, paginate: true)
|
128
129
|
search = current_taxonomy_search
|
129
130
|
search = [search, params[:search]].select(&:present?).join(' AND ')
|
130
|
-
scope.search_for(search, :order => params[:order])
|
131
|
-
|
131
|
+
scope = scope.search_for(search, :order => params[:order])
|
132
|
+
scope = scope.paginate(:page => params[:page], :per_page => params[:per_page]) if paginate
|
133
|
+
scope.distinct
|
132
134
|
end
|
133
135
|
|
134
136
|
def current_taxonomy_search
|
@@ -9,13 +9,13 @@ module Actions
|
|
9
9
|
def plan(_host_type, host_name, facts, certname, proxy_id)
|
10
10
|
facts['domain'].try(:downcase!)
|
11
11
|
host = if SETTINGS[:version].short > '1.16'
|
12
|
-
::Host::
|
12
|
+
::Host::Managed.import_host(host_name, certname)
|
13
13
|
else
|
14
14
|
# backwards compatibility
|
15
15
|
::Host::Managed.import_host(host_name, facts['_type'], certname, proxy_id)
|
16
16
|
end
|
17
17
|
host.save(:validate => false) if host.new_record?
|
18
|
-
action_subject(host, :facts => facts)
|
18
|
+
action_subject(host, :facts => facts.to_unsafe_h, :proxy_id => proxy_id)
|
19
19
|
if host.build?
|
20
20
|
::Foreman::Logging.logger('foreman-tasks').info "Skipping importing of facts for #{host.name} because it's in build mode"
|
21
21
|
else
|
@@ -26,7 +26,7 @@ module Actions
|
|
26
26
|
def run
|
27
27
|
::User.as :admin do
|
28
28
|
host = ::Host.find(input[:host][:id])
|
29
|
-
state = host.import_facts(input[:facts])
|
29
|
+
state = host.import_facts(input[:facts], proxy)
|
30
30
|
output[:state] = state
|
31
31
|
end
|
32
32
|
rescue ::Foreman::Exception => e
|
@@ -36,6 +36,10 @@ module Actions
|
|
36
36
|
raise e unless e.code == 'ERF51-9911'
|
37
37
|
end
|
38
38
|
|
39
|
+
def proxy
|
40
|
+
SmartProxy.find_by(id: input[:proxy_id]) if input[:proxy_id].present?
|
41
|
+
end
|
42
|
+
|
39
43
|
def rescue_strategy
|
40
44
|
::Dynflow::Action::Rescue::Skip
|
41
45
|
end
|
@@ -64,9 +64,9 @@ module Actions
|
|
64
64
|
task
|
65
65
|
end
|
66
66
|
rescue => e
|
67
|
-
# We could not reach the remote task, we
|
67
|
+
# We could not reach the remote task, we'll try again next time
|
68
68
|
action.action_logger.warn(_('Failed to check on tasks on proxy at %{url}: %{exception}') % { :url => url, :exception => e.message })
|
69
|
-
|
69
|
+
[]
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
@@ -51,7 +51,8 @@ module ForemanTasks
|
|
51
51
|
:complete_value => true,
|
52
52
|
:rename => 'owner.id',
|
53
53
|
:ext_method => :search_by_owner,
|
54
|
-
:validator => ->(value) { ScopedSearch::Validators::INTEGER.call(value) || value == 'current_user' }
|
54
|
+
:validator => ->(value) { ScopedSearch::Validators::INTEGER.call(value) || value == 'current_user' },
|
55
|
+
:aliases => ['user.id']
|
55
56
|
scoped_search :relation => :owners, :on => :login, :complete_value => true, :rename => 'owner.login', :ext_method => :search_by_owner, :aliases => [:user]
|
56
57
|
scoped_search :relation => :owners, :on => :firstname, :complete_value => true, :rename => 'owner.firstname', :ext_method => :search_by_owner
|
57
58
|
scoped_search :relation => :task_groups, :on => :id, :complete_value => true, :rename => 'task_group.id', :validator => ScopedSearch::Validators::INTEGER
|
@@ -85,8 +86,24 @@ module ForemanTasks
|
|
85
86
|
delayed? ? N_('Delayed') : N_('Immediate')
|
86
87
|
end
|
87
88
|
|
89
|
+
def get_humanized(method)
|
90
|
+
attr = case method
|
91
|
+
when :humanized_name
|
92
|
+
:action
|
93
|
+
when :humanized_input
|
94
|
+
:input
|
95
|
+
when :humanized_output
|
96
|
+
:output
|
97
|
+
end
|
98
|
+
if attr
|
99
|
+
humanized[attr]
|
100
|
+
else
|
101
|
+
_('N/A')
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
88
105
|
def humanized
|
89
|
-
{ action:
|
106
|
+
{ action: action,
|
90
107
|
input: '',
|
91
108
|
output: '' }
|
92
109
|
end
|
@@ -158,6 +175,20 @@ module ForemanTasks
|
|
158
175
|
# using uniq suffix to avoid colisions when searching by two different owners via ScopedSearch
|
159
176
|
uniq_suffix = SecureRandom.hex(3)
|
160
177
|
key_name = connection.quote_column_name(key.sub(/^.*\./, ''))
|
178
|
+
value.sub!('*', '%%')
|
179
|
+
condition = if key.blank?
|
180
|
+
sanitize_sql_for_conditions(["users#{uniq_suffix}.login #{operator} ? or users#{uniq_suffix}.firstname #{operator} ? ", value, value])
|
181
|
+
elsif key =~ /\.id\Z/
|
182
|
+
value = User.current.id if value == 'current_user'
|
183
|
+
sanitize_sql_for_conditions(["foreman_tasks_locks_owner#{uniq_suffix}.resource_id #{operator} ?", value])
|
184
|
+
else
|
185
|
+
placeholder, value = operator == 'IN' ? ['(?)', value.split(',').map(&:strip)] : ['?', value]
|
186
|
+
sanitize_sql_for_conditions(["users#{uniq_suffix}.#{key_name} #{operator} #{placeholder}", value])
|
187
|
+
end
|
188
|
+
{ :conditions => condition, :joins => joins_for_user_search(key, uniq_suffix) }
|
189
|
+
end
|
190
|
+
|
191
|
+
def self.joins_for_user_search(key, uniq_suffix)
|
161
192
|
joins = <<-SQL
|
162
193
|
INNER JOIN foreman_tasks_locks AS foreman_tasks_locks_owner#{uniq_suffix}
|
163
194
|
ON (foreman_tasks_locks_owner#{uniq_suffix}.task_id = foreman_tasks_tasks.id AND
|
@@ -170,15 +201,7 @@ module ForemanTasks
|
|
170
201
|
ON (users#{uniq_suffix}.id = foreman_tasks_locks_owner#{uniq_suffix}.resource_id)
|
171
202
|
SQL
|
172
203
|
end
|
173
|
-
|
174
|
-
sanitize_sql_for_conditions(["users#{uniq_suffix}.login #{operator} ? or users#{uniq_suffix}.firstname #{operator} ? ", value, value])
|
175
|
-
elsif key =~ /\.id\Z/
|
176
|
-
value = User.current.id if value == 'current_user'
|
177
|
-
sanitize_sql_for_conditions(["foreman_tasks_locks_owner#{uniq_suffix}.resource_id #{operator} ?", value])
|
178
|
-
else
|
179
|
-
sanitize_sql_for_conditions(["users#{uniq_suffix}.#{key_name} #{operator} ?", value])
|
180
|
-
end
|
181
|
-
{ :conditions => condition, :joins => joins }
|
204
|
+
joins
|
182
205
|
end
|
183
206
|
|
184
207
|
def progress
|
@@ -5,6 +5,7 @@ class Setting::ForemanTasks < Setting
|
|
5
5
|
|
6
6
|
transaction do
|
7
7
|
[
|
8
|
+
set('foreman_tasks_sync_task_timeout', N_('Number of seconds to wait for synchronous task to finish.'), 120),
|
8
9
|
set('dynflow_allow_dangerous_actions', N_('Allow unlocking actions which can have dangerous consequences.'), false),
|
9
10
|
set('dynflow_enable_console', N_('Enable the dynflow console (/foreman_tasks/dynflow) for debugging'), true),
|
10
11
|
set('dynflow_console_require_auth', N_('Require user to be authenticated as user with admin rights when accessing dynflow console'), true),
|
data/foreman-tasks.gemspec
CHANGED
@@ -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", '~> 1.0', '>= 1.1.
|
32
|
+
s.add_dependency "dynflow", '~> 1.0', '>= 1.1.1'
|
33
33
|
s.add_dependency "sinatra" # for Dynflow web console
|
34
34
|
s.add_dependency "parse-cron", '~> 0.1.4'
|
35
35
|
s.add_dependency "get_process_mem" # for memory polling
|
data/lib/foreman_tasks.rb
CHANGED
@@ -27,8 +27,15 @@ module ForemanTasks
|
|
27
27
|
raise error
|
28
28
|
end),
|
29
29
|
(on ::Dynflow::World::Triggered.call(execution_plan_id: ~any, future: ~any) do |id, finished|
|
30
|
-
|
31
|
-
|
30
|
+
unless async
|
31
|
+
timeout = Setting['foreman_tasks_sync_task_timeout']
|
32
|
+
finished.wait(timeout)
|
33
|
+
task = ForemanTasks::Task::DynflowTask.where(:external_id => id).first
|
34
|
+
if task.nil? || task.pending?
|
35
|
+
raise TimeoutError, "The time waiting for task #{task.try(:id)} to finish exceeded the 'foreman_tasks_sync_task_timeout' (#{timeout}s)"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
task || ForemanTasks::Task::DynflowTask.where(:external_id => id).first!
|
32
39
|
end)
|
33
40
|
end
|
34
41
|
end
|
data/lib/foreman_tasks/engine.rb
CHANGED
@@ -115,8 +115,12 @@ module ForemanTasks
|
|
115
115
|
|
116
116
|
initializer 'foreman_tasks.require_dynflow', :before => 'foreman_tasks.initialize_dynflow' do |_app|
|
117
117
|
ForemanTasks.dynflow.require!
|
118
|
-
::ForemanTasks.dynflow.config.on_init do |world|
|
118
|
+
::ForemanTasks.dynflow.config.on_init(false) do |world|
|
119
|
+
world.middleware.use Actions::Middleware::KeepCurrentTaxonomies
|
119
120
|
world.middleware.use Actions::Middleware::KeepCurrentUser
|
121
|
+
end
|
122
|
+
|
123
|
+
::ForemanTasks.dynflow.config.on_init do |world|
|
120
124
|
ForemanTasksCore.dynflow_setup(world)
|
121
125
|
end
|
122
126
|
end
|
@@ -24,6 +24,14 @@ module ForemanTasks
|
|
24
24
|
Organization.current = Location.current = nil
|
25
25
|
end
|
26
26
|
|
27
|
+
it 'supports csv export' do
|
28
|
+
FactoryBot.create(:some_task, :action => 'Some action')
|
29
|
+
get(:index, params: { format: :csv }, session: set_session_user)
|
30
|
+
assert_response :success
|
31
|
+
assert_equal 2, response.body.lines.size
|
32
|
+
assert_include response.body.lines[1], 'Some action'
|
33
|
+
end
|
34
|
+
|
27
35
|
describe 'taxonomy scoping' do
|
28
36
|
let(:organizations) { (0..1).map { FactoryBot.create(:organization) } }
|
29
37
|
let(:tasks) { organizations.map { |o| linked_task(o) } + [FactoryBot.create(:some_task)] }
|
data/test/unit/task_test.rb
CHANGED
@@ -21,6 +21,24 @@ class TasksTest < ActiveSupport::TestCase
|
|
21
21
|
test 'can search the tasks by current_user in combination with implicit search' do
|
22
22
|
assert_equal [@task_one], ForemanTasks::Task.search_for("owner.id = current_user AND #{@task_one.label}")
|
23
23
|
end
|
24
|
+
|
25
|
+
test 'can search the tasks by user' do
|
26
|
+
assert_equal [@task_one], ForemanTasks::Task.search_for("user = #{@user_one.login}")
|
27
|
+
end
|
28
|
+
|
29
|
+
test 'can search the tasks by user\'s id' do
|
30
|
+
assert_equal [@task_one], ForemanTasks::Task.search_for("user.id = #{@user_one.id}")
|
31
|
+
assert_equal [@task_one], ForemanTasks::Task.search_for("owner.id = #{@user_one.id}")
|
32
|
+
end
|
33
|
+
|
34
|
+
test 'can search the tasks by user with wildcards' do
|
35
|
+
glob = '*' + @user_one.login[1..-1] # search for '*ser1' if login is 'user1'
|
36
|
+
assert_equal [@task_one], ForemanTasks::Task.search_for("user ~ #{glob}")
|
37
|
+
end
|
38
|
+
|
39
|
+
test 'can search the tasks by array' do
|
40
|
+
assert_equal [@task_one], ForemanTasks::Task.search_for("user ^ (this_user, #{@user_one.login}, that_user)")
|
41
|
+
end
|
24
42
|
end
|
25
43
|
|
26
44
|
describe 'authorization filtering' do
|
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.14.
|
4
|
+
version: 0.14.1
|
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: 2018-
|
11
|
+
date: 2018-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: foreman-tasks-core
|
@@ -33,7 +33,7 @@ dependencies:
|
|
33
33
|
version: '1.0'
|
34
34
|
- - ">="
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: 1.1.
|
36
|
+
version: 1.1.1
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '1.0'
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 1.1.
|
46
|
+
version: 1.1.1
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: sinatra
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -297,7 +297,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
297
297
|
version: '0'
|
298
298
|
requirements: []
|
299
299
|
rubyforge_project:
|
300
|
-
rubygems_version: 2.
|
300
|
+
rubygems_version: 2.7.3
|
301
301
|
signing_key:
|
302
302
|
specification_version: 4
|
303
303
|
summary: Foreman plugin for showing tasks information for resoruces and users
|