19
19
20
20
package org .elasticsearch .action .admin .cluster .node .tasks .cancel ;
21
21
22
+ import org .elasticsearch .ElasticsearchSecurityException ;
23
+ import org .elasticsearch .ExceptionsHelper ;
22
24
import org .elasticsearch .ResourceNotFoundException ;
23
25
import org .elasticsearch .Version ;
24
26
import org .elasticsearch .action .ActionListener ;
@@ -121,8 +123,12 @@ void cancelTaskAndDescendants(CancellableTask task, String reason, boolean waitF
121
123
StepListener <Void > banOnNodesListener = new StepListener <>();
122
124
setBanOnNodes (reason , waitForCompletion , task , childrenNodes , banOnNodesListener );
123
125
banOnNodesListener .whenComplete (groupedListener ::onResponse , groupedListener ::onFailure );
126
+ // If we start unbanning when the last child task completed and that child task executed with a specific user, then unban
127
+ // requests are denied because internal requests can't run with a user. We need to remove bans with the current thread context.
128
+ final Runnable removeBansRunnable = transportService .getThreadPool ().getThreadContext ()
129
+ .preserveContext (() -> removeBanOnNodes (task , childrenNodes ));
124
130
// We remove bans after all child tasks are completed although in theory we can do it on a per-node basis.
125
- completedListener .whenComplete (r -> removeBanOnNodes ( task , childrenNodes ), e -> removeBanOnNodes ( task , childrenNodes ));
131
+ completedListener .whenComplete (r -> removeBansRunnable . run ( ), e -> removeBansRunnable . run ( ));
126
132
// if wait_for_completion is true, then only return when (1) bans are placed on child nodes, (2) child tasks are
127
133
// completed or failed, (3) the main task is cancelled. Otherwise, return after bans are placed on child nodes.
128
134
if (waitForCompletion ) {
@@ -162,6 +168,7 @@ public void handleResponse(TransportResponse.Empty response) {
162
168
163
169
@ Override
164
170
public void handleException (TransportException exp ) {
171
+ assert ExceptionsHelper .unwrapCause (exp ) instanceof ElasticsearchSecurityException == false ;
165
172
logger .warn ("Cannot send ban for tasks with the parent [{}] to the node [{}]" , banRequest .parentTaskId , node );
166
173
groupedListener .onFailure (exp );
167
174
}
@@ -174,7 +181,13 @@ private void removeBanOnNodes(CancellableTask task, Collection<DiscoveryNode> ch
174
181
BanParentTaskRequest .createRemoveBanParentTaskRequest (new TaskId (clusterService .localNode ().getId (), task .getId ()));
175
182
for (DiscoveryNode node : childNodes ) {
176
183
logger .trace ("Sending remove ban for tasks with the parent [{}] to the node [{}]" , request .parentTaskId , node );
177
- transportService .sendRequest (node , BAN_PARENT_ACTION_NAME , request , EmptyTransportResponseHandler .INSTANCE_SAME );
184
+ transportService .sendRequest (node , BAN_PARENT_ACTION_NAME , request , new EmptyTransportResponseHandler (ThreadPool .Names .SAME ) {
185
+ @ Override
186
+ public void handleException (TransportException exp ) {
187
+ assert ExceptionsHelper .unwrapCause (exp ) instanceof ElasticsearchSecurityException == false ;
188
+ logger .info ("failed to remove the parent ban for task {} on node {}" , request .parentTaskId , node );
189
+ }
190
+ });
178
191
}
179
192
}
180
193
0 commit comments