|
@@ -15,6 +15,7 @@ import org.elasticsearch.common.settings.Setting;
|
|
|
import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.common.settings.SettingsException;
|
|
|
import org.elasticsearch.common.util.LazyInitializable;
|
|
|
+import org.elasticsearch.core.Tuple;
|
|
|
import org.elasticsearch.logging.LogManager;
|
|
|
import org.elasticsearch.logging.Logger;
|
|
|
import org.elasticsearch.xpack.core.watcher.actions.Action;
|
|
@@ -121,34 +122,28 @@ public class WebhookService extends NotificationService<WebhookService.WebhookAc
|
|
|
Map<String, Object> model = Variables.createCtxParamsMap(ctx, payload);
|
|
|
|
|
|
// Render the original request
|
|
|
- HttpRequest request = action.getRequest().render(templateEngine, model);
|
|
|
+ HttpRequest originalRequest = action.getRequest().render(templateEngine, model);
|
|
|
|
|
|
- // If applicable, add the extra token to the headers
|
|
|
- boolean tokenAdded = false;
|
|
|
- WebhookAccount account = getAccount(NAME);
|
|
|
- if (this.additionalTokenEnabled && account.hostTokenMap.size() > 0) {
|
|
|
- // Generate a string like example.com:9200 to match against the list of hosts where the
|
|
|
- // additional token should be provided. The token will only be added to the headers if
|
|
|
- // the request matches the list.
|
|
|
- String reqHostAndPort = request.host() + ":" + request.port();
|
|
|
- if (Strings.hasText(account.hostTokenMap.get(reqHostAndPort))) {
|
|
|
- // Add the additional token
|
|
|
- tokenAdded = true;
|
|
|
- request = request.copy().setHeader(TOKEN_HEADER_NAME, account.hostTokenMap.get(reqHostAndPort)).build();
|
|
|
- }
|
|
|
+ if (ctx.simulateAction(actionId)) {
|
|
|
+ HttpRequest request = maybeModifyHttpRequest(originalRequest);
|
|
|
+ // If the request was modified, then the request has had the token added
|
|
|
+ boolean tokenAdded = originalRequest != request;
|
|
|
+ // Skip execution, return only the simulated (and redacted if necessary) response
|
|
|
+ return new WebhookAction.Result.Simulated(
|
|
|
+ tokenAdded ? request.copy().setHeader(TOKEN_HEADER_NAME, WatcherXContentParser.REDACTED_PASSWORD).build() : request
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
+ final Tuple<HttpRequest, HttpResponse> respTup = modifyAndExecuteHttpRequest(originalRequest);
|
|
|
+ final HttpRequest request = respTup.v1();
|
|
|
+ final HttpResponse response = respTup.v2();
|
|
|
+ // If the request was modified, then the request has had the token added
|
|
|
+ final boolean tokenAdded = originalRequest != request;
|
|
|
+
|
|
|
final Function<HttpRequest, HttpRequest> redactToken = tokenAdded
|
|
|
? req -> req.copy().setHeader(TOKEN_HEADER_NAME, WatcherXContentParser.REDACTED_PASSWORD).build()
|
|
|
: Function.identity();
|
|
|
|
|
|
- if (ctx.simulateAction(actionId)) {
|
|
|
- // Skip execution, return only the simulated (and redacted if necessary) response
|
|
|
- return new WebhookAction.Result.Simulated(redactToken.apply(request));
|
|
|
- }
|
|
|
-
|
|
|
- HttpResponse response = httpClient.execute(request);
|
|
|
-
|
|
|
if (response.status() >= 400) {
|
|
|
return new WebhookAction.Result.Failure(redactToken.apply(request), response);
|
|
|
} else {
|
|
@@ -156,6 +151,51 @@ public class WebhookService extends NotificationService<WebhookService.WebhookAc
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Makes any additional modifications to the {@link HttpRequest} if necessary.
|
|
|
+ * If no modifications are made the same instance is returned, otherwise a new
|
|
|
+ * HttpRequest is returned.
|
|
|
+ */
|
|
|
+ HttpRequest maybeModifyHttpRequest(HttpRequest request) {
|
|
|
+ WebhookAccount account = getAccount(NAME);
|
|
|
+ if (this.additionalTokenEnabled && account.hostTokenMap.size() > 0) {
|
|
|
+ // Generate a string like example.com:9200 to match against the list of hosts where the
|
|
|
+ // additional token should be provided. The token will only be added to the headers if
|
|
|
+ // the request matches the list.
|
|
|
+ String reqHostAndPort = request.host() + ":" + request.port();
|
|
|
+ if (Strings.hasText(account.hostTokenMap.get(reqHostAndPort))) {
|
|
|
+ // Add the additional token
|
|
|
+ logger.debug(
|
|
|
+ "additional [{}] header token added to watcher webhook request for {}://{}:{}",
|
|
|
+ TOKEN_HEADER_NAME,
|
|
|
+ request.scheme().scheme(),
|
|
|
+ request.host(),
|
|
|
+ request.port()
|
|
|
+ );
|
|
|
+ return request.copy().setHeader(TOKEN_HEADER_NAME, account.hostTokenMap.get(reqHostAndPort)).build();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return request;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Executes the given {@link HttpRequest} after any necessary modifications.
|
|
|
+ * A tuple of the modified (or unmodified) {@link HttpRequest} and
|
|
|
+ * {@link HttpResponse} is returned.
|
|
|
+ */
|
|
|
+ public Tuple<HttpRequest, HttpResponse> modifyAndExecuteHttpRequest(HttpRequest request) throws IOException {
|
|
|
+ final HttpRequest modifiedRequest = maybeModifyHttpRequest(request);
|
|
|
+ final HttpResponse response = httpClient.execute(modifiedRequest);
|
|
|
+ logger.debug(
|
|
|
+ "executed watcher webhook request for {}://{}:{}, response code: {}",
|
|
|
+ modifiedRequest.scheme().scheme(),
|
|
|
+ modifiedRequest.host(),
|
|
|
+ modifiedRequest.port(),
|
|
|
+ response.status()
|
|
|
+ );
|
|
|
+ return Tuple.tuple(modifiedRequest, response);
|
|
|
+ }
|
|
|
+
|
|
|
public static final class WebhookAccount {
|
|
|
private final Map<String, String> hostTokenMap;
|
|
|
|