foreman-tasks 3.0.1 → 3.0.6
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/api/tasks_controller.rb +18 -3
- data/app/models/foreman_tasks/recurring_logic.rb +3 -3
- data/app/models/foreman_tasks/task/dynflow_task.rb +8 -3
- data/app/models/foreman_tasks/task/search.rb +2 -1
- data/app/views/foreman_tasks/layouts/react.html.erb +1 -2
- data/app/views/foreman_tasks/tasks/dashboard/_latest_tasks_in_error_warning.html.erb +1 -1
- data/app/views/foreman_tasks/tasks/dashboard/_tasks_status.html.erb +1 -1
- data/app/views/foreman_tasks/tasks/show.html.erb +1 -6
- data/foreman-tasks.gemspec +1 -0
- data/lib/foreman_tasks/version.rb +1 -1
- data/test/unit/recurring_logic_test.rb +6 -0
- data/test/unit/task_test.rb +10 -0
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +10 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableHelpers.js +0 -8
- data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +13 -4
- data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.scss +0 -10
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +0 -2
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionNameCellFormatter.test.js.snap +3 -1
- data/webpack/ForemanTasks/Components/TasksTable/formatters/actionNameCellFormatter.js +6 -1
- metadata +8 -8
- data/app/assets/stylesheets/foreman_tasks/tasks.scss +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29e160b9773db8ef5b9f8cb9e26011b957578caccf2d56bc6a57852c5553df9d
|
4
|
+
data.tar.gz: 863c9436e788ede17b6e2a80aae49b259f96a1372c80a004ed66e70409957435
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4140dea3980dcbbc2d140b3e83dc23458a53ff6be35f5012feb8d3bd87c24ed45e98eb98a19aaf7228c1ca620f4e91e57236cc4c17e36754bd1cbe65dd1b3249
|
7
|
+
data.tar.gz: e2836f3e5061587913504a69509e21fab8e640f002cf026641d8948e64f830c8abf1aa4b7d72e9a9c64f49c47116ac94be299367b6fba9d44689d410f1805cb3
|
@@ -75,11 +75,16 @@ module ForemanTasks
|
|
75
75
|
end
|
76
76
|
|
77
77
|
api :POST, '/tasks/bulk_resume', N_('Resume all paused error tasks')
|
78
|
+
desc <<~DOC
|
79
|
+
Resumes all selected resumable tasks. If neither a search query nor an
|
80
|
+
explicit list of task IDs is provided, it tries to resume all tasks in
|
81
|
+
paused state with result error.
|
82
|
+
DOC
|
78
83
|
param :search, String, :desc => N_('Resume tasks matching search string')
|
79
84
|
param :task_ids, Array, :desc => N_('Resume specific tasks by ID')
|
80
85
|
def bulk_resume
|
81
86
|
if params[:search].nil? && params[:task_ids].nil?
|
82
|
-
|
87
|
+
params[:search] = 'state = paused and result = error'
|
83
88
|
end
|
84
89
|
resumed = []
|
85
90
|
failed = []
|
@@ -109,9 +114,14 @@ module ForemanTasks
|
|
109
114
|
}
|
110
115
|
end
|
111
116
|
|
112
|
-
api :POST, '/tasks/bulk_cancel', N_('Cancel
|
117
|
+
api :POST, '/tasks/bulk_cancel', N_('Cancel selected cancellable tasks')
|
118
|
+
desc <<~DOC
|
119
|
+
Cancels all selected cancellable tasks. Requires a search query or an
|
120
|
+
explicit list of task IDs to be provided.
|
121
|
+
DOC
|
113
122
|
param :search, String, :desc => N_('Cancel tasks matching search string')
|
114
123
|
param :task_ids, Array, :desc => N_('Cancel specific tasks by ID')
|
124
|
+
error :bad_request, 'Returned if neither search nor task_ids parameter is provided.'
|
115
125
|
def bulk_cancel
|
116
126
|
if params[:search].nil? && params[:task_ids].nil?
|
117
127
|
raise BadRequest, _('Please provide at least one of search or task_ids parameters in the request')
|
@@ -130,9 +140,14 @@ module ForemanTasks
|
|
130
140
|
}
|
131
141
|
end
|
132
142
|
|
133
|
-
api :POST, '/tasks/bulk_stop', N_('Stop
|
143
|
+
api :POST, '/tasks/bulk_stop', N_('Stop selected stoppable tasks')
|
144
|
+
desc <<~DOC
|
145
|
+
Stops all selected tasks which are not already stopped. Requires a
|
146
|
+
search query or an explicit list of task IDs to be provided.
|
147
|
+
DOC
|
134
148
|
param :search, String, :desc => N_('Stop tasks matching search string')
|
135
149
|
param :task_ids, Array, :desc => N_('Stop specific tasks by ID')
|
150
|
+
error :bad_request, 'Returned if neither search nor task_ids parameter is provided.'
|
136
151
|
def bulk_stop
|
137
152
|
if params[:search].nil? && params[:task_ids].nil?
|
138
153
|
raise BadRequest, _('Please provide at least one of search or task_ids parameters in the request')
|
@@ -31,12 +31,12 @@ module ForemanTasks
|
|
31
31
|
if value
|
32
32
|
task.update!(:start_at => next_occurrence_time) if task.start_at < Time.zone.now
|
33
33
|
update(:state => 'active')
|
34
|
-
else
|
35
|
-
update(:state => 'disabled')
|
36
34
|
end
|
37
|
-
|
35
|
+
elsif value
|
38
36
|
raise RecurringLogicCancelledException
|
39
37
|
end
|
38
|
+
|
39
|
+
update(:state => 'disabled') unless value
|
40
40
|
end
|
41
41
|
|
42
42
|
def enabled?
|
@@ -140,12 +140,17 @@ module ForemanTasks
|
|
140
140
|
|
141
141
|
def main_action
|
142
142
|
return @main_action if defined?(@main_action)
|
143
|
+
|
144
|
+
@main_action = execution_plan && execution_plan.root_plan_step.try(:action, execution_plan)
|
143
145
|
if active_job?
|
144
146
|
job_data = active_job_data
|
145
|
-
|
146
|
-
|
147
|
-
|
147
|
+
begin
|
148
|
+
@main_action = active_job_action(job_data['job_class'], job_data['arguments'])
|
149
|
+
rescue => e
|
150
|
+
Foreman::Logging.exception("Failed to load ActiveJob for task #{id}", e, :logger => 'foreman-tasks')
|
151
|
+
end
|
148
152
|
end
|
153
|
+
@main_action
|
149
154
|
end
|
150
155
|
|
151
156
|
# The class for ActiveJob jobs in Dynflow, JobWrapper is not expected to
|
@@ -20,7 +20,8 @@ module ForemanTasks
|
|
20
20
|
foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_type = '#{resource_type}')
|
21
21
|
SQL
|
22
22
|
# Select only those tasks which either have the correct taxonomy or are not related to any
|
23
|
-
sql = "foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id #{operator} ? OR foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id IS NULL"
|
23
|
+
sql = "foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id #{operator} (?) OR foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id IS NULL"
|
24
|
+
value = value.split(',') if operator.index(/IN/i)
|
24
25
|
{ :conditions => sanitize_sql_for_conditions([sql, value]), :joins => joins }
|
25
26
|
end
|
26
27
|
|
@@ -9,7 +9,6 @@
|
|
9
9
|
<%= notifications %>
|
10
10
|
<div id="organization-id" data-id="<%= Organization.current.id if Organization.current %>" ></div>
|
11
11
|
<div id="user-id" data-id="<%= User.current.id if User.current %>" ></div>
|
12
|
-
|
12
|
+
<%= react_component('ForemanTasks') %>
|
13
13
|
<% end %>
|
14
14
|
<%= render file: "layouts/base" %>
|
15
|
-
<%= mount_react_component('ForemanTasks', '#foremanTasksReactRoot') %>
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<td class="ellipsis"><%= link_to task.humanized[:action], defined?(main_app) ? main_app.foreman_tasks_task_path(task.id) : foreman_tasks_task_path(task.id) %></td>
|
12
12
|
<td><%= task.state %></td>
|
13
13
|
<td><%= task.result %></td>
|
14
|
-
<td><%= task.started_at ?
|
14
|
+
<td><%= task.started_at ? date_time_relative(task.started_at) : _('N/A') %></td>
|
15
15
|
</tr>
|
16
16
|
<% end %>
|
17
17
|
</table>
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<td><%= result.state %></td>
|
12
12
|
<td><%= result.result %></td>
|
13
13
|
<td><%= link_to result.count, main_app.foreman_tasks_tasks_path(:search => "state=#{result.state}&result=#{result.result}") %></td>
|
14
|
-
<td><%= result.started_at ?
|
14
|
+
<td><%= result.started_at ? date_time_relative(result.started_at) : _('N/A') %></td>
|
15
15
|
</tr>
|
16
16
|
<% end %>
|
17
17
|
</table>
|
data/foreman-tasks.gemspec
CHANGED
@@ -7,6 +7,7 @@ require "foreman_tasks/version"
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "foreman-tasks"
|
9
9
|
s.version = ForemanTasks::VERSION
|
10
|
+
s.license = 'GPL-3.0'
|
10
11
|
s.authors = ["Ivan Nečas"]
|
11
12
|
s.email = ["inecas@redhat.com"]
|
12
13
|
s.homepage = "https://github.com/theforeman/foreman-tasks"
|
@@ -148,6 +148,12 @@ class RecurringLogicsTest < ActiveSupport::TestCase
|
|
148
148
|
assert ForemanTasks.dynflow.world.persistence.load_delayed_plan(task.execution_plan.id).frozen
|
149
149
|
end
|
150
150
|
|
151
|
+
it 'handles if the task has been deleted' do
|
152
|
+
logic.tasks.find_by(:state => 'scheduled').destroy
|
153
|
+
logic.update!(:enabled => false)
|
154
|
+
assert_equal 'disabled', logic.state
|
155
|
+
end
|
156
|
+
|
151
157
|
it 'properly re-enables on disable' do
|
152
158
|
logic.update!(:enabled => false)
|
153
159
|
logic.update!(:enabled => true)
|
data/test/unit/task_test.rb
CHANGED
@@ -129,6 +129,16 @@ class TasksTest < ActiveSupport::TestCase
|
|
129
129
|
_ { proc { ForemanTasks::Task.search_for('duration = "25 potatoes"') } }.must_raise ScopedSearch::QueryNotSupported
|
130
130
|
end
|
131
131
|
end
|
132
|
+
|
133
|
+
context 'by taxonomies' do
|
134
|
+
test 'can search by taxonomies using IN' do
|
135
|
+
assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('location_id ^ (1)').first }
|
136
|
+
assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('organization_id ^ (1)').first }
|
137
|
+
assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('location_id ^ (1,2)').first }
|
138
|
+
assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('organization_id ^ (1,2)').first }
|
139
|
+
assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('organization_id = 1').first }
|
140
|
+
end
|
141
|
+
end
|
132
142
|
end
|
133
143
|
|
134
144
|
describe 'users' do
|
@@ -14,14 +14,6 @@ export const getApiPathname = url => {
|
|
14
14
|
return uri.pathname().replace('foreman_tasks/', 'foreman_tasks/api/');
|
15
15
|
};
|
16
16
|
|
17
|
-
export const resolveSearchQuery = (search, history) => {
|
18
|
-
const uriQuery = {
|
19
|
-
search,
|
20
|
-
page: 1,
|
21
|
-
};
|
22
|
-
updateURlQuery(uriQuery, history);
|
23
|
-
};
|
24
|
-
|
25
17
|
export const getCSVurl = (path, query) => {
|
26
18
|
let url = new URI(path);
|
27
19
|
url = url.pathname(`${url.pathname()}.csv`);
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import PropTypes from 'prop-types';
|
3
|
+
import URI from 'urijs';
|
3
4
|
import { getURIsearch } from 'foremanReact/common/urlHelpers';
|
4
5
|
import { Spinner, Button, Icon } from 'patternfly-react';
|
5
6
|
import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
|
@@ -10,7 +11,7 @@ import { STATUS } from 'foremanReact/constants';
|
|
10
11
|
import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
|
11
12
|
import TasksDashboard from '../TasksDashboard';
|
12
13
|
import TasksTable from './TasksTable';
|
13
|
-
import {
|
14
|
+
import { getCSVurl, updateURlQuery } from './TasksTableHelpers';
|
14
15
|
import ConfirmModal from './Components/ConfirmModal/';
|
15
16
|
import {
|
16
17
|
TASKS_SEARCH_PROPS,
|
@@ -35,8 +36,17 @@ const TasksTablePage = ({
|
|
35
36
|
}) => {
|
36
37
|
const url = history.location.pathname + history.location.search;
|
37
38
|
const uriQuery = getURIQuery(url);
|
38
|
-
const onSearch =
|
39
|
-
|
39
|
+
const onSearch = search => {
|
40
|
+
const uri = new URI(url);
|
41
|
+
if (uri.search(true).search === search && uri.search(true).page === '1') {
|
42
|
+
props.getTableItems(uri);
|
43
|
+
} else {
|
44
|
+
const newUriQuery = {
|
45
|
+
search,
|
46
|
+
page: 1,
|
47
|
+
};
|
48
|
+
updateURlQuery(newUriQuery, history);
|
49
|
+
}
|
40
50
|
};
|
41
51
|
|
42
52
|
const { setModalOpen, setModalClosed } = useForemanModal({
|
@@ -60,7 +70,6 @@ const TasksTablePage = ({
|
|
60
70
|
onSearch={onSearch}
|
61
71
|
header={createHeader(props.actionName)}
|
62
72
|
breadcrumbOptions={getBreadcrumbs(props.actionName)}
|
63
|
-
toastNotifications="foreman-tasks-cancel"
|
64
73
|
toolbarButtons={
|
65
74
|
<React.Fragment>
|
66
75
|
<Button onClick={() => props.reloadPage(url, props.parentTaskID)}>
|
data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap
CHANGED
@@ -66,7 +66,6 @@ exports[`TasksTablePage rendering render with Breadcrubs and edit permissions 1`
|
|
66
66
|
}
|
67
67
|
searchQuery="a=b"
|
68
68
|
searchable={true}
|
69
|
-
toastNotifications="foreman-tasks-cancel"
|
70
69
|
toolbarButtons={
|
71
70
|
<React.Fragment>
|
72
71
|
<Button
|
@@ -202,7 +201,6 @@ exports[`TasksTablePage rendering render with minimal props 1`] = `
|
|
202
201
|
}
|
203
202
|
searchQuery="a=b"
|
204
203
|
searchable={true}
|
205
|
-
toastNotifications="foreman-tasks-cancel"
|
206
204
|
toolbarButtons={
|
207
205
|
<React.Fragment>
|
208
206
|
<Button
|
@@ -1,5 +1,10 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { cellFormatter } from 'foremanReact/components/common/table';
|
3
|
+
import EllipsisWithTooltip from 'react-ellipsis-with-tooltip';
|
3
4
|
|
4
5
|
export const actionNameCellFormatter = url => (value, { rowData: { id } }) =>
|
5
|
-
cellFormatter(
|
6
|
+
cellFormatter(
|
7
|
+
<a href={`/${url}/${id}`}>
|
8
|
+
<EllipsisWithTooltip>{value}</EllipsisWithTooltip>
|
9
|
+
</a>
|
10
|
+
);
|
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: 3.0.
|
4
|
+
version: 3.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Nečas
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dynflow
|
@@ -137,7 +137,6 @@ files:
|
|
137
137
|
- app/assets/javascripts/foreman_tasks/foreman_tasks.js
|
138
138
|
- app/assets/javascripts/foreman_tasks/trigger_form.js
|
139
139
|
- app/assets/stylesheets/foreman_tasks/foreman_tasks.css
|
140
|
-
- app/assets/stylesheets/foreman_tasks/tasks.scss
|
141
140
|
- app/assets/stylesheets/foreman_tasks/trigger_form.css
|
142
141
|
- app/controllers/foreman_tasks/api/recurring_logics_controller.rb
|
143
142
|
- app/controllers/foreman_tasks/api/tasks_controller.rb
|
@@ -586,9 +585,10 @@ files:
|
|
586
585
|
- webpack/stories/decorators/index.js
|
587
586
|
- webpack/stories/decorators/withCardsDecorator.js
|
588
587
|
homepage: https://github.com/theforeman/foreman-tasks
|
589
|
-
licenses:
|
588
|
+
licenses:
|
589
|
+
- GPL-3.0
|
590
590
|
metadata: {}
|
591
|
-
post_install_message:
|
591
|
+
post_install_message:
|
592
592
|
rdoc_options: []
|
593
593
|
require_paths:
|
594
594
|
- lib
|
@@ -603,8 +603,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
603
603
|
- !ruby/object:Gem::Version
|
604
604
|
version: '0'
|
605
605
|
requirements: []
|
606
|
-
rubygems_version: 3.
|
607
|
-
signing_key:
|
606
|
+
rubygems_version: 3.1.2
|
607
|
+
signing_key:
|
608
608
|
specification_version: 4
|
609
609
|
summary: Foreman plugin for showing tasks information for resources and users
|
610
610
|
test_files:
|