foreman-tasks 0.15.11 → 0.16.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/app/controllers/foreman_tasks/tasks_controller.rb +14 -19
- data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +0 -20
- data/app/lib/actions/bulk_action.rb +1 -1
- data/app/models/foreman_tasks/lock.rb +0 -9
- data/app/models/foreman_tasks/task.rb +12 -74
- data/app/models/foreman_tasks/task/dynflow_task.rb +2 -1
- data/app/models/foreman_tasks/task/search.rb +52 -0
- data/app/views/foreman_tasks/tasks/index.html.erb +0 -3
- data/app/views/foreman_tasks/tasks/show.html.erb +9 -1
- data/db/migrate/20180927120509_add_user_id.foreman_tasks.rb +40 -0
- data/lib/foreman_tasks/dynflow/persistence.rb +0 -1
- data/lib/foreman_tasks/tasks/export_tasks.rake +1 -1
- data/lib/foreman_tasks/version.rb +1 -1
- data/test/controllers/tasks_controller_test.rb +0 -46
- data/test/factories/task_factory.rb +0 -8
- data/test/unit/actions/bulk_action_test.rb +0 -2
- data/test/unit/dynflow_console_authorizer_test.rb +1 -1
- data/test/unit/task_test.rb +6 -2
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/PausedTasksCard.js +1 -6
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/__snapshots__/PausedTasksCard.test.js.snap +0 -2
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/RunningTasksCard.js +1 -6
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/__snapshots__/RunningTasksCard.test.js.snap +0 -2
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.js +6 -3
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.scss +3 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/__snapshots__/ScheduledTasksCard.test.js.snap +0 -3
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.js +0 -2
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.scss +4 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCardHelper.js +3 -3
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCard.test.js.snap +54 -495
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.js +0 -1
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.scss +0 -6
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChart.scss +3 -0
- metadata +6 -5
- data/test/helpers/foreman_tasks/foreman_tasks_helper_test.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a562e9a32057e45cbf20bcc2d511ee03580cee1181af686965683bccfc1d6f8e
|
4
|
+
data.tar.gz: bcffaac1d9efb02ef8677394c7af554058aad577d5e1a7ce9b32c66ac21206f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7acf7b281043c1ad3a3c0fcb45436258caf1f11a06295c5e4b69b43f8bbe5ea450d61e25346d638198c72596e1ac3e86fdad1eff2f092d4fc3254cb8e551d5f
|
7
|
+
data.tar.gz: e5c9234ef7ccd241c17ef37892a79d04b6de918034d1e305093bea7b54ce125dce88cb1c9360f4a7dab1674eefbd00db20b3848a445ea297eeaab37c271cd855
|
@@ -12,18 +12,26 @@ module ForemanTasks
|
|
12
12
|
|
13
13
|
def index
|
14
14
|
params[:order] ||= 'started_at DESC'
|
15
|
-
|
15
|
+
respond_to do |format|
|
16
|
+
format.html do
|
17
|
+
@tasks = filter(resource_base)
|
18
|
+
render :index, layout: !request.xhr?
|
19
|
+
end
|
20
|
+
format.csv do
|
21
|
+
@tasks = filter(resource_base, paginate: false)
|
22
|
+
csv_response(@tasks, [:id, :action, :state, :result, 'started_at.in_time_zone', 'ended_at.in_time_zone', :username], ['Id', 'Action', 'State', 'Result', 'Started At', 'Ended At', 'User'])
|
23
|
+
end
|
24
|
+
end
|
16
25
|
end
|
17
26
|
|
18
27
|
def summary
|
19
|
-
|
20
|
-
render json: Task::Summarizer.new(Task.where(:id => scope), params[:recent_timeframe].to_i).summary
|
28
|
+
render json: Task::Summarizer.new(resource_base, params[:recent_timeframe].to_i).summary
|
21
29
|
end
|
22
30
|
|
23
31
|
def sub_tasks
|
24
|
-
|
25
|
-
@
|
26
|
-
|
32
|
+
task = resource_base.find(params[:id])
|
33
|
+
@tasks = filter(task.sub_tasks)
|
34
|
+
render :index
|
27
35
|
end
|
28
36
|
|
29
37
|
def cancel_step
|
@@ -95,19 +103,6 @@ module ForemanTasks
|
|
95
103
|
|
96
104
|
private
|
97
105
|
|
98
|
-
def respond_with_tasks(scope)
|
99
|
-
respond_to do |format|
|
100
|
-
format.html do
|
101
|
-
@tasks = filter(scope)
|
102
|
-
render :index, layout: !request.xhr?
|
103
|
-
end
|
104
|
-
format.csv do
|
105
|
-
@tasks = filter(scope, paginate: false)
|
106
|
-
csv_response(@tasks, [:id, :action, :state, :result, 'started_at.in_time_zone', 'ended_at.in_time_zone', :username], ['Id', 'Action', 'State', 'Result', 'Started At', 'Ended At', 'User'])
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
106
|
def restrict_dangerous_actions
|
112
107
|
render_403 unless Setting['dynflow_allow_dangerous_actions']
|
113
108
|
end
|
@@ -122,26 +122,6 @@ module ForemanTasks
|
|
122
122
|
render :partial => 'common/trigger_form', :locals => { :f => f, :triggering => triggering }
|
123
123
|
end
|
124
124
|
|
125
|
-
def task_breadcrumb_item(task, active = false)
|
126
|
-
item = { :caption => format_task_input(task) }
|
127
|
-
item[:url] = url_for(foreman_tasks_task_path(task.id)) unless active
|
128
|
-
item
|
129
|
-
end
|
130
|
-
|
131
|
-
def index_breadcrumb_item
|
132
|
-
item = { :caption => _('Tasks') }
|
133
|
-
item[:url] = foreman_tasks_tasks_url if action_name != 'index'
|
134
|
-
item
|
135
|
-
end
|
136
|
-
|
137
|
-
def breadcrumb_items
|
138
|
-
items = [index_breadcrumb_item]
|
139
|
-
return items if action_name == 'index'
|
140
|
-
items << task_breadcrumb_item(@task, action_name == 'show')
|
141
|
-
items << { :caption => _('Sub tasks') } if action_name == 'sub_tasks'
|
142
|
-
items
|
143
|
-
end
|
144
|
-
|
145
125
|
private
|
146
126
|
|
147
127
|
def future_mode_fieldset(f, triggering)
|
@@ -46,7 +46,7 @@ module Actions
|
|
46
46
|
def create_sub_plans
|
47
47
|
action_class = input[:action_class].constantize
|
48
48
|
target_class = input[:target_class].constantize
|
49
|
-
targets = target_class.
|
49
|
+
targets = target_class.where(:id => current_batch)
|
50
50
|
|
51
51
|
missing = Array.new((current_batch - targets.map(&:id)).count) { nil }
|
52
52
|
|
@@ -118,11 +118,6 @@ module ForemanTasks
|
|
118
118
|
build_link(resource, uuid).available?
|
119
119
|
end
|
120
120
|
|
121
|
-
# Records the information about the user that triggered the task
|
122
|
-
def owner!(user, uuid)
|
123
|
-
build_owner(user, uuid).save!
|
124
|
-
end
|
125
|
-
|
126
121
|
private
|
127
122
|
|
128
123
|
def all_lock_names(resource, include_links = false)
|
@@ -166,10 +161,6 @@ module ForemanTasks
|
|
166
161
|
build(uuid, resource, LINK_LOCK_NAME, false)
|
167
162
|
end
|
168
163
|
|
169
|
-
def build_owner(user, uuid = nil)
|
170
|
-
build(uuid, user, OWNER_LOCK_NAME, false)
|
171
|
-
end
|
172
|
-
|
173
164
|
def build(uuid, resource, lock_name, exclusive)
|
174
165
|
new(task_id: uuid,
|
175
166
|
name: lock_name,
|
@@ -3,6 +3,7 @@ require 'securerandom'
|
|
3
3
|
module ForemanTasks
|
4
4
|
class Task < ApplicationRecord
|
5
5
|
include Authorizable
|
6
|
+
extend Search
|
6
7
|
|
7
8
|
def check_permissions_after_save
|
8
9
|
# there's no create_tasks permission, tasks are created as a result of internal actions, in such case we
|
@@ -29,10 +30,7 @@ module ForemanTasks
|
|
29
30
|
has_many :task_groups, :through => :task_group_members
|
30
31
|
has_many :recurring_logic_task_groups, -> { where :type => 'ForemanTasks::TaskGroups::RecurringLogicTaskGroup' },
|
31
32
|
:through => :task_group_members, :source => :task_group
|
32
|
-
|
33
|
-
# specify has_one relation though has_many relation
|
34
|
-
has_many :owners, -> { where(['foreman_tasks_locks.name = ?', Lock::OWNER_LOCK_NAME]) },
|
35
|
-
:through => :locks, :source => :resource, :source_type => 'User'
|
33
|
+
belongs_to :user
|
36
34
|
|
37
35
|
scoped_search :on => :id, :complete_value => false
|
38
36
|
scoped_search :on => :action, :complete_value => false
|
@@ -46,17 +44,15 @@ module ForemanTasks
|
|
46
44
|
scoped_search :on => :parent_task_id, :complete_value => true
|
47
45
|
scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'location_id', :ext_method => :search_by_taxonomy, :only_explicit => true
|
48
46
|
scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'organization_id', :ext_method => :search_by_taxonomy, :only_explicit => true
|
49
|
-
scoped_search :relation => :locks, :on => :resource_type, :complete_value => true, :rename => 'resource_type', :ext_method => :search_by_generic_resource
|
50
|
-
scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'resource_id', :ext_method => :search_by_generic_resource
|
51
|
-
scoped_search :
|
52
|
-
:on => :id,
|
47
|
+
scoped_search :relation => :locks, :on => :resource_type, :complete_value => true, :rename => 'resource_type', :ext_method => :search_by_generic_resource, :only_explicit => true
|
48
|
+
scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'resource_id', :ext_method => :search_by_generic_resource, :only_explicit => true
|
49
|
+
scoped_search :on => :user_id,
|
53
50
|
:complete_value => true,
|
54
|
-
:rename => '
|
55
|
-
:ext_method => :search_by_owner,
|
51
|
+
:rename => 'user.id',
|
56
52
|
:validator => ->(value) { ScopedSearch::Validators::INTEGER.call(value) || value == 'current_user' },
|
57
|
-
:aliases => ['
|
58
|
-
scoped_search :relation => :
|
59
|
-
scoped_search :relation => :
|
53
|
+
:aliases => ['owner.id'], :ext_method => :search_by_owner, :only_explicit => true
|
54
|
+
scoped_search :relation => :user, :on => :login, :rename => 'user.login', :complete_value => true, :aliases => ['owner.login', 'user'], :ext_method => :search_by_owner, :only_explicit => true
|
55
|
+
scoped_search :relation => :user, :on => :firstname, :rename => 'user.firstname', :complete_value => true, :aliases => ['owner.firstname'], :ext_method => :search_by_owner, :only_explicit => true
|
60
56
|
scoped_search :relation => :task_groups, :on => :id, :complete_value => true, :rename => 'task_group.id', :validator => ScopedSearch::Validators::INTEGER
|
61
57
|
|
62
58
|
scope :active, -> { where('foreman_tasks_tasks.state != ?', :stopped) }
|
@@ -77,11 +73,11 @@ module ForemanTasks
|
|
77
73
|
end
|
78
74
|
|
79
75
|
def owner
|
80
|
-
|
76
|
+
user
|
81
77
|
end
|
82
78
|
|
83
79
|
def username
|
84
|
-
owner
|
80
|
+
owner
|
85
81
|
end
|
86
82
|
|
87
83
|
def execution_type
|
@@ -150,7 +146,7 @@ module ForemanTasks
|
|
150
146
|
|
151
147
|
# used by Foreman notifications framework
|
152
148
|
def notification_recipients_ids
|
153
|
-
|
149
|
+
[owner.id]
|
154
150
|
end
|
155
151
|
|
156
152
|
def build_notifications
|
@@ -165,64 +161,6 @@ module ForemanTasks
|
|
165
161
|
notifications
|
166
162
|
end
|
167
163
|
|
168
|
-
def self.search_by_generic_resource(key, operator, value)
|
169
|
-
key = 'resource_type' if key.blank?
|
170
|
-
key_name = connection.quote_column_name(key.sub(/^.*\./, ''))
|
171
|
-
condition = sanitize_sql_for_conditions(["foreman_tasks_locks.#{key_name} #{operator} ?", value])
|
172
|
-
|
173
|
-
{ :conditions => condition, :joins => :locks }
|
174
|
-
end
|
175
|
-
|
176
|
-
def self.search_by_taxonomy(key, operator, value)
|
177
|
-
uniq_suffix = SecureRandom.hex(3)
|
178
|
-
resource_type = key == 'location_id' ? 'Location' : 'Organization'
|
179
|
-
|
180
|
-
joins = <<-SQL
|
181
|
-
LEFT JOIN foreman_tasks_locks AS foreman_tasks_locks_taxonomy#{uniq_suffix}
|
182
|
-
ON (foreman_tasks_locks_taxonomy#{uniq_suffix}.task_id = foreman_tasks_tasks.id AND
|
183
|
-
foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_type = '#{resource_type}')
|
184
|
-
SQL
|
185
|
-
# Select only those tasks which either have the correct taxonomy or are not related to any
|
186
|
-
sql = "foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id #{operator} ? OR foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id IS NULL"
|
187
|
-
{ :conditions => sanitize_sql_for_conditions([sql, value]), :joins => joins }
|
188
|
-
end
|
189
|
-
|
190
|
-
def self.search_by_owner(key, operator, value)
|
191
|
-
return { :conditions => '0 = 1' } if value == 'current_user' && User.current.nil?
|
192
|
-
|
193
|
-
key = 'owners.login' if key == 'user'
|
194
|
-
# using uniq suffix to avoid colisions when searching by two different owners via ScopedSearch
|
195
|
-
uniq_suffix = SecureRandom.hex(3)
|
196
|
-
key_name = connection.quote_column_name(key.sub(/^.*\./, ''))
|
197
|
-
value.sub!('*', '%%')
|
198
|
-
condition = if key.blank?
|
199
|
-
sanitize_sql_for_conditions(["users#{uniq_suffix}.login #{operator} ? or users#{uniq_suffix}.firstname #{operator} ? ", value, value])
|
200
|
-
elsif key =~ /\.id\Z/
|
201
|
-
value = User.current.id if value == 'current_user'
|
202
|
-
sanitize_sql_for_conditions(["foreman_tasks_locks_owner#{uniq_suffix}.resource_id #{operator} ?", value])
|
203
|
-
else
|
204
|
-
placeholder, value = operator == 'IN' ? ['(?)', value.split(',').map(&:strip)] : ['?', value]
|
205
|
-
sanitize_sql_for_conditions(["users#{uniq_suffix}.#{key_name} #{operator} #{placeholder}", value])
|
206
|
-
end
|
207
|
-
{ :conditions => condition, :joins => joins_for_user_search(key, uniq_suffix) }
|
208
|
-
end
|
209
|
-
|
210
|
-
def self.joins_for_user_search(key, uniq_suffix)
|
211
|
-
joins = <<-SQL
|
212
|
-
INNER JOIN foreman_tasks_locks AS foreman_tasks_locks_owner#{uniq_suffix}
|
213
|
-
ON (foreman_tasks_locks_owner#{uniq_suffix}.task_id = foreman_tasks_tasks.id AND
|
214
|
-
foreman_tasks_locks_owner#{uniq_suffix}.resource_type = 'User' AND
|
215
|
-
foreman_tasks_locks_owner#{uniq_suffix}.name = '#{Lock::OWNER_LOCK_NAME}')
|
216
|
-
SQL
|
217
|
-
if key !~ /\.id\Z/
|
218
|
-
joins << <<-SQL
|
219
|
-
INNER JOIN users as users#{uniq_suffix}
|
220
|
-
ON (users#{uniq_suffix}.id = foreman_tasks_locks_owner#{uniq_suffix}.resource_id)
|
221
|
-
SQL
|
222
|
-
end
|
223
|
-
joins
|
224
|
-
end
|
225
|
-
|
226
164
|
def progress
|
227
165
|
case state.to_s
|
228
166
|
when 'running', 'paused'
|
@@ -208,7 +208,8 @@ module ForemanTasks
|
|
208
208
|
def self.new_for_execution_plan(execution_plan_id, data)
|
209
209
|
new(:external_id => execution_plan_id,
|
210
210
|
:state => data[:state].to_s,
|
211
|
-
:result => data[:result].to_s
|
211
|
+
:result => data[:result].to_s,
|
212
|
+
:user_id => User.current.try(:id))
|
212
213
|
end
|
213
214
|
|
214
215
|
def self.model_name
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module ForemanTasks
|
2
|
+
class Task
|
3
|
+
module Search
|
4
|
+
def search_by_generic_resource(key, operator, value)
|
5
|
+
key = 'resource_type' if key.blank?
|
6
|
+
key_name = connection.quote_column_name(key.sub(/^.*\./, ''))
|
7
|
+
condition = sanitize_sql_for_conditions(["foreman_tasks_locks.#{key_name} #{operator} ?", value])
|
8
|
+
|
9
|
+
{ :conditions => condition, :joins => :locks }
|
10
|
+
end
|
11
|
+
|
12
|
+
def search_by_taxonomy(key, operator, value)
|
13
|
+
uniq_suffix = SecureRandom.hex(3)
|
14
|
+
resource_type = key == 'location_id' ? 'Location' : 'Organization'
|
15
|
+
|
16
|
+
joins = <<-SQL
|
17
|
+
LEFT JOIN foreman_tasks_locks AS foreman_tasks_locks_taxonomy#{uniq_suffix}
|
18
|
+
ON (foreman_tasks_locks_taxonomy#{uniq_suffix}.task_id = foreman_tasks_tasks.id AND
|
19
|
+
foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_type = '#{resource_type}')
|
20
|
+
SQL
|
21
|
+
# Select only those tasks which either have the correct taxonomy or are not related to any
|
22
|
+
sql = "foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id #{operator} ? OR foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id IS NULL"
|
23
|
+
{ :conditions => sanitize_sql_for_conditions([sql, value]), :joins => joins }
|
24
|
+
end
|
25
|
+
|
26
|
+
def search_by_owner(key, operator, value)
|
27
|
+
return { :conditions => '0 = 1' } if value == 'current_user' && User.current.nil?
|
28
|
+
|
29
|
+
key = 'owners.login' if key == 'user'
|
30
|
+
# using uniq suffix to avoid colisions when searching by two different owners via ScopedSearch
|
31
|
+
uniq_suffix = SecureRandom.hex(3)
|
32
|
+
key_name = connection.quote_column_name(key.sub(/^.*\./, ''))
|
33
|
+
value.sub!('*', '%%')
|
34
|
+
condition = if key.blank?
|
35
|
+
sanitize_sql_for_conditions(["users_#{uniq_suffix}.login #{operator} ? or users_#{uniq_suffix}.firstname #{operator} ? ", value, value])
|
36
|
+
elsif key =~ /\.id\Z/
|
37
|
+
value = User.current.id if value == 'current_user'
|
38
|
+
sanitize_sql_for_conditions(["foreman_tasks_tasks.user_id #{operator} ?", value])
|
39
|
+
else
|
40
|
+
placeholder, value = operator == 'IN' ? ['(?)', value.split(',').map(&:strip)] : ['?', value]
|
41
|
+
sanitize_sql_for_conditions(["users_#{uniq_suffix}.#{key_name} #{operator} #{placeholder}", value])
|
42
|
+
end
|
43
|
+
{ :conditions => condition, :joins => joins_for_user_search(key, uniq_suffix) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def joins_for_user_search(key, uniq_suffix)
|
47
|
+
return '' if key =~ /\.id\Z/
|
48
|
+
"INNER JOIN users AS users_#{uniq_suffix} ON users_#{uniq_suffix}.id = foreman_tasks_tasks.user_id"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -1,7 +1,15 @@
|
|
1
1
|
<% stylesheet 'foreman_tasks/tasks' %>
|
2
2
|
|
3
3
|
<%= breadcrumbs(
|
4
|
-
items:
|
4
|
+
items: [
|
5
|
+
{
|
6
|
+
caption: _('Tasks'),
|
7
|
+
url: url_for(foreman_tasks_tasks_path)
|
8
|
+
},
|
9
|
+
{
|
10
|
+
caption: format_task_input(@task)
|
11
|
+
}
|
12
|
+
],
|
5
13
|
name_field: 'action',
|
6
14
|
resource_url: foreman_tasks_api_tasks_path,
|
7
15
|
switcher_item_url: foreman_tasks_task_path(:id => ':id')
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class AddUserId < ActiveRecord::Migration[5.0]
|
2
|
+
def up
|
3
|
+
add_reference :foreman_tasks_tasks, :user, :foreign_key => true
|
4
|
+
|
5
|
+
return if User.unscoped.find_by(:login => User::ANONYMOUS_ADMIN).nil?
|
6
|
+
User.as_anonymous_admin do
|
7
|
+
user_locks.select(:resource_id).distinct.pluck(:resource_id).each do |owner_id|
|
8
|
+
tasks = ForemanTasks::Task.joins(:locks).where(:locks => user_locks.where(:resource_id => owner_id))
|
9
|
+
tasks.update_all(:user_id => owner_id)
|
10
|
+
user_locks.where(:resource_id => owner_id).delete_all
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def down
|
16
|
+
User.as_anonymous_admin do
|
17
|
+
ForemanTasks::Task.select(:user_id).distinct.pluck(:user_id).compact.each do |user_id|
|
18
|
+
ForemanTasks::Task.where(:user_id => user_id).select(:id).find_in_batches do |group|
|
19
|
+
group.each { |task| create_lock user_id, task }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
remove_column :foreman_tasks_tasks, :user_id
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def create_lock(user_id, task)
|
30
|
+
ForemanTasks::Lock.new(:name => ForemanTasks::Lock::OWNER_LOCK_NAME,
|
31
|
+
:resource_type => User.name,
|
32
|
+
:resource_id => user_id,
|
33
|
+
:task_id => task.id,
|
34
|
+
:exclusive => false).save!
|
35
|
+
end
|
36
|
+
|
37
|
+
def user_locks
|
38
|
+
ForemanTasks::Lock.where(:name => ForemanTasks::Lock::OWNER_LOCK_NAME)
|
39
|
+
end
|
40
|
+
end
|
@@ -36,7 +36,6 @@ module ForemanTasks
|
|
36
36
|
when :planning
|
37
37
|
task = ::ForemanTasks::Task::DynflowTask.where(:external_id => execution_plan_id).first
|
38
38
|
task.update_from_dynflow(data)
|
39
|
-
Lock.owner!(::User.current, task.id) if ::User.current && ::User.current.id.present?
|
40
39
|
else
|
41
40
|
if (task = ::ForemanTasks::Task::DynflowTask.where(:external_id => execution_plan_id).first)
|
42
41
|
unless task.state.to_s == data[:state].to_s
|
@@ -244,7 +244,6 @@ namespace :foreman_tasks do
|
|
244
244
|
|
245
245
|
tasks = ForemanTasks::Task.search_for(filter)
|
246
246
|
|
247
|
-
puts _("Exporting all tasks matching filter #{filter}")
|
248
247
|
puts _("Gathering #{tasks.count} tasks.")
|
249
248
|
if format == 'html'
|
250
249
|
Dir.mktmpdir('task-export') do |tmp_dir|
|
@@ -256,6 +255,7 @@ namespace :foreman_tasks do
|
|
256
255
|
tasks.each_with_index do |task, count|
|
257
256
|
File.open(File.join(tmp_dir, "#{task.id}.html"), 'w') { |file| file.write(PageHelper.pagify(renderer.render_task(task))) }
|
258
257
|
puts "#{count + 1}/#{total}"
|
258
|
+
count += 1
|
259
259
|
end
|
260
260
|
|
261
261
|
File.open(File.join(tmp_dir, 'index.html'), 'w') { |file| file.write(PageHelper.pagify(PageHelper.generate_index(tasks))) }
|
@@ -41,41 +41,6 @@ module ForemanTasks
|
|
41
41
|
response = JSON.parse(@response.body)
|
42
42
|
assert_equal 0, response['stopped']['total']
|
43
43
|
end
|
44
|
-
|
45
|
-
describe 'taxonomy scoping' do
|
46
|
-
before do
|
47
|
-
@organizations = [0, 0].map { FactoryBot.create(:organization) }
|
48
|
-
@locations = [0, 0].map { FactoryBot.create(:location) }
|
49
|
-
@tasks = [0, 0].map { FactoryBot.create(:some_task) }
|
50
|
-
@tasks.zip(@organizations, @locations).each do |task, org, loc|
|
51
|
-
Lock.link!(org, task.id)
|
52
|
-
Lock.link!(loc, task.id)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'does not limit if unset' do
|
57
|
-
get(:summary, params: { recent_timeframe: 24 }, session: set_session_user)
|
58
|
-
assert_response :success
|
59
|
-
response = JSON.parse(@response.body)
|
60
|
-
assert_equal 2, response['stopped']['total']
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'finds only tasks with matching taxonomies' do
|
64
|
-
get(:summary, params: { recent_timeframe: 24 },
|
65
|
-
session: set_session_user.merge(:organization_id => @organizations.first, :location_id => @locations.first))
|
66
|
-
assert_response :success
|
67
|
-
response = JSON.parse(@response.body)
|
68
|
-
assert_equal 1, response['stopped']['total']
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'find no tasks when taxonomy combination contains no tasks' do
|
72
|
-
get(:summary, params: { recent_timeframe: 24 },
|
73
|
-
session: set_session_user.merge(:organization_id => @organizations.first, :location_id => @locations.last))
|
74
|
-
assert_response :success
|
75
|
-
response = JSON.parse(@response.body)
|
76
|
-
assert_equal 0, response['stopped']['total']
|
77
|
-
end
|
78
|
-
end
|
79
44
|
end
|
80
45
|
|
81
46
|
it 'supports csv export' do
|
@@ -102,17 +67,6 @@ module ForemanTasks
|
|
102
67
|
session: set_session_user(User.current)
|
103
68
|
assert_response :not_found
|
104
69
|
end
|
105
|
-
|
106
|
-
it 'supports csv export' do
|
107
|
-
parent = FactoryBot.create(:some_task, :action => 'Some action')
|
108
|
-
child = FactoryBot.create(:some_task, :action => 'Child action')
|
109
|
-
child.parent_task_id = parent.id
|
110
|
-
child.save!
|
111
|
-
get(:sub_tasks, params: { id: parent.id, format: :csv }, session: set_session_user)
|
112
|
-
assert_response :success
|
113
|
-
assert_equal 2, response.body.lines.size
|
114
|
-
assert_include response.body.lines[1], 'Child action'
|
115
|
-
end
|
116
70
|
end
|
117
71
|
|
118
72
|
describe 'taxonomy scoping' do
|