Merge remote-tracking branch 'origin/master' into strict-booleans

Original commit: elastic/x-pack-elasticsearch@36ae65f4d8
This commit is contained in:
Daniel Mitterdorfer 2017-01-13 10:11:37 +01:00
commit d90181a3a1
31 changed files with 412 additions and 157 deletions

View File

@ -22,12 +22,10 @@ public class PreBuiltXPackTransportClientTests extends RandomizedTest {
@Test
public void testPluginInstalled() {
// TODO: remove when Netty 4.1.6 is upgraded to Netty 4.1.7 including https://github.com/netty/netty/pull/6068
assumeFalse(Constants.JRE_IS_MINIMUM_JAVA9);
try (TransportClient client = new PreBuiltXPackTransportClient(Settings.EMPTY)) {
Settings settings = client.settings();
assertEquals(Security.NAME4, NetworkModule.TRANSPORT_TYPE_SETTING.get(settings));
}
}
}
}

View File

@ -40,7 +40,6 @@ import org.elasticsearch.plugins.ScriptPlugin;
import org.elasticsearch.rest.RestHandler;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.SearchRequestParsers;
import org.elasticsearch.threadpool.ExecutorBuilder;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.Transport;
@ -96,7 +95,6 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@ -221,7 +219,7 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
@Override
public Collection<Object> createComponents(Client client, ClusterService clusterService, ThreadPool threadPool,
ResourceWatcherService resourceWatcherService, ScriptService scriptService,
SearchRequestParsers searchRequestParsers, NamedXContentRegistry xContentRegistry) {
NamedXContentRegistry xContentRegistry) {
List<Object> components = new ArrayList<>();
components.add(sslService);
@ -255,7 +253,7 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
httpTemplateParser, scriptService, httpAuthRegistry);
components.addAll(notificationComponents);
components.addAll(watcher.createComponents(getClock(), scriptService, internalClient, searchRequestParsers, licenseState,
components.addAll(watcher.createComponents(getClock(), scriptService, internalClient, licenseState,
httpClient, httpTemplateParser, threadPool, clusterService, security.getCryptoService(), xContentRegistry, components));

View File

@ -7,7 +7,6 @@ package org.elasticsearch.xpack.common.http;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;

View File

@ -87,7 +87,7 @@ public class RestGraphAction extends XPackRestHandler {
Hop currentHop = graphRequest.createNextHop(null);
try (XContentParser parser = request.contentOrSourceParamParser()) {
QueryParseContext context = new QueryParseContext(parser, parseFieldMatcher);
QueryParseContext context = new QueryParseContext(parser);
XContentParser.Token token = parser.nextToken();
@ -115,7 +115,7 @@ public class RestGraphAction extends XPackRestHandler {
if (token == XContentParser.Token.START_ARRAY) {
if (VERTICES_FIELD.match(fieldName)) {
parseVertices(parser, context, currentHop, graphRequest);
parseVertices(parser, currentHop);
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (QUERY_FIELD.match(fieldName)) {
@ -135,12 +135,10 @@ public class RestGraphAction extends XPackRestHandler {
} else {
throw new ElasticsearchParseException("Illegal property in graph definition " + fieldName, token.name());
}
}
}
private void parseVertices(XContentParser parser, QueryParseContext context, Hop currentHop, GraphExploreRequest graphRequest)
private void parseVertices(XContentParser parser, Hop currentHop)
throws IOException {
XContentParser.Token token;
@ -324,7 +322,6 @@ public class RestGraphAction extends XPackRestHandler {
} else {
throw new ElasticsearchParseException("Unknown object property: [" + fieldName + "]");
}
}
}
}

View File

@ -91,7 +91,7 @@ public class Exporters extends AbstractLifecycleComponent implements Iterable<Ex
try {
ExportBulk bulk = exporter.openBulk();
if (bulk == null) {
logger.info("skipping exporter [{}] as it is not ready yet", exporter.name());
logger.debug("skipping exporter [{}] as it is not ready yet", exporter.name());
} else {
bulks.add(bulk);
}

View File

@ -79,6 +79,7 @@ public class LocalExporter extends Exporter implements ClusterStateListener, Cle
private final AtomicReference<State> state = new AtomicReference<>(State.INITIALIZED);
private final AtomicBoolean installingSomething = new AtomicBoolean(false);
private final AtomicBoolean waitedForSetup = new AtomicBoolean(false);
public LocalExporter(Exporter.Config config, InternalClient client,
ClusterService clusterService, CleanerService cleanerService) {
@ -122,6 +123,7 @@ public class LocalExporter extends Exporter implements ClusterStateListener, Cle
public void doClose() {
if (state.getAndSet(State.TERMINATED) != State.TERMINATED) {
logger.trace("stopped");
// we also remove the listener in resolveBulk after we get to RUNNING, but it's okay to double-remove
clusterService.removeListener(this);
cleanerService.remove(this);
}
@ -143,17 +145,31 @@ public class LocalExporter extends Exporter implements ClusterStateListener, Cle
final Map<String, String> templates = StreamSupport.stream(new ResolversRegistry(Settings.EMPTY).spliterator(), false)
.collect(Collectors.toMap(MonitoringIndexNameResolver::templateName, MonitoringIndexNameResolver::template, (a, b) -> a));
// if this is not the master, we just need to make sure the master has set things up
boolean setup = true;
// elected master node needs to setup templates; non-master nodes need to wait for it to be setup
if (clusterService.state().nodes().isLocalNodeElectedMaster()) {
if (setupIfElectedMaster(clusterState, templates) == false) {
return null;
}
setup = setupIfElectedMaster(clusterState, templates);
} else if (setupIfNotElectedMaster(clusterState, templates.keySet()) == false) {
// the first pass will be false so that we don't bother users if the master took one-go to setup
if (waitedForSetup.getAndSet(true)) {
logger.info("waiting for elected master node [{}] to setup local exporter [{}] (does it have x-pack installed?)",
clusterService.state().nodes().getMasterNode(), config.name());
}
setup = false;
}
// any failure/delay to setup the local exporter stops it until the next pass (10s by default)
if (setup == false) {
return null;
}
if (state.compareAndSet(State.INITIALIZED, State.RUNNING)) {
logger.debug("started");
// we no longer need to receive cluster state updates
clusterService.removeListener(this);
}
return new LocalBulk(name(), logger, client, resolvers, config.settings().getAsBoolean(USE_INGEST_PIPELINE_SETTING, true));

View File

@ -8,8 +8,6 @@ package org.elasticsearch.xpack.notification.email.attachment;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParseFieldMatcherSupplier;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.logging.LoggerMessageFormat;
@ -49,10 +47,9 @@ public class ReportingAttachmentParser implements EmailAttachmentParser<Reportin
public static final Setting<Integer> RETRIES_SETTING =
Setting.intSetting("xpack.notification.reporting.retries", 40, 0, Setting.Property.NodeScope);
private static final ObjectParser<Builder, AuthParseFieldMatcher> PARSER = new ObjectParser<>("reporting_attachment");
private static final ObjectParser<KibanaReportingPayload, ParseFieldMatcherSupplier> PAYLOAD_PARSER =
private static final ObjectParser<Builder, AuthParseContext> PARSER = new ObjectParser<>("reporting_attachment");
private static final ObjectParser<KibanaReportingPayload, Void> PAYLOAD_PARSER =
new ObjectParser<>("reporting_attachment_kibana_payload", true, null);
private static final ParseFieldMatcherSupplier STRICT_PARSING = () -> ParseFieldMatcher.STRICT;
static {
PARSER.declareInt(Builder::retries, new ParseField("retries"));
@ -88,7 +85,7 @@ public class ReportingAttachmentParser implements EmailAttachmentParser<Reportin
@Override
public ReportingAttachment parse(String id, XContentParser parser) throws IOException {
Builder builder = new Builder(id);
PARSER.parse(parser, builder, new AuthParseFieldMatcher(authRegistry));
PARSER.parse(parser, builder, new AuthParseContext(authRegistry));
return builder.build();
}
@ -199,7 +196,7 @@ public class ReportingAttachmentParser implements EmailAttachmentParser<Reportin
// EMPTY is safe here becaus we never call namedObject
try (XContentParser parser = JsonXContent.jsonXContent.createParser(NamedXContentRegistry.EMPTY, body)) {
KibanaReportingPayload payload = new KibanaReportingPayload();
PAYLOAD_PARSER.parse(parser, payload, STRICT_PARSING);
PAYLOAD_PARSER.parse(parser, payload, null);
String path = payload.getPath();
if (Strings.isEmpty(path)) {
throw new ElasticsearchException("Watch[{}] reporting[{}] field path found in JSON payload, payload was {}",
@ -213,20 +210,15 @@ public class ReportingAttachmentParser implements EmailAttachmentParser<Reportin
* A helper class to parse the HTTPAuth data, which is read by an old school pull parser, that is handed over in the ctor.
* See the static parser definition at the top
*/
private static class AuthParseFieldMatcher implements ParseFieldMatcherSupplier {
private static class AuthParseContext {
private final HttpAuthRegistry authRegistry;
AuthParseFieldMatcher(HttpAuthRegistry authRegistry) {
AuthParseContext(HttpAuthRegistry authRegistry) {
this.authRegistry = authRegistry;
}
@Override
public ParseFieldMatcher getParseFieldMatcher() {
return ParseFieldMatcher.EMPTY;
}
public HttpAuth parseAuth(XContentParser parser) {
HttpAuth parseAuth(XContentParser parser) {
try {
return authRegistry.parse(parser);
} catch (IOException e) {

View File

@ -100,13 +100,8 @@ public class SecurityActionFilter extends AbstractComponent implements ActionFil
}
if (licenseState.isAuthAllowed()) {
// only restore the context if it is not empty. This is needed because sometimes a response is sent to the user
// and then a cleanup action is executed (like for search without a scroll)
final boolean restoreOriginalContext = securityContext.getAuthentication() != null;
final boolean useSystemUser = AuthorizationUtils.shouldReplaceUserWithSystem(threadContext, action);
// we should always restore the original here because we forcefully changed to the system user
final ThreadContext.StoredContext toRestore =
restoreOriginalContext || useSystemUser ? threadContext.newStoredContext() : () -> {};
final ThreadContext.StoredContext toRestore = threadContext.newStoredContext();
final ActionListener<ActionResponse> signingListener = new ContextPreservingActionListener<>(threadContext, toRestore,
ActionListener.wrap(r -> {
try {
@ -127,7 +122,9 @@ public class SecurityActionFilter extends AbstractComponent implements ActionFil
}
});
} else {
applyInternal(action, request, authenticatedListener);
try (ThreadContext.StoredContext ignore = threadContext.newStoredContext()) {
applyInternal(action, request, authenticatedListener);
}
}
} catch (Exception e) {
listener.onFailure(e);

View File

@ -11,12 +11,9 @@ import org.elasticsearch.xpack.security.authz.IndicesAndAliasesResolver;
import org.elasticsearch.xpack.security.authz.permission.FieldPermissions;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static java.util.Collections.unmodifiableSet;
/**
* Encapsulates the field and document permissions per concrete index based on the current request.
*/

View File

@ -7,7 +7,6 @@ package org.elasticsearch.xpack.ssl;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
@ -19,11 +18,8 @@ import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.cli.EnvironmentAwareCommand;
import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParseFieldMatcherSupplier;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
@ -31,9 +27,9 @@ import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.env.Environment;
import org.elasticsearch.node.internal.InternalSettingsPreparer;
import org.elasticsearch.xpack.XPackPlugin;
import javax.security.auth.x500.X500Principal;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
@ -62,8 +58,6 @@ import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.security.auth.x500.X500Principal;
/**
* CLI tool to make generation of certificates or certificate requests easier for users
*/
@ -80,9 +74,9 @@ public class CertificateTool extends EnvironmentAwareCommand {
Pattern.compile("[a-zA-Z0-9!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1," + MAX_FILENAME_LENGTH + "}");
private static final int DEFAULT_KEY_SIZE = 2048;
private static final ObjectParser<List<CertificateInformation>, CertInfoParseContext> PARSER = new ObjectParser<>("certgen");
private static final ObjectParser<List<CertificateInformation>, Void> PARSER = new ObjectParser<>("certgen");
static {
ConstructingObjectParser<CertificateInformation, CertInfoParseContext> instanceParser =
ConstructingObjectParser<CertificateInformation, Void> instanceParser =
new ConstructingObjectParser<>("instances",
a -> new CertificateInformation((String) a[0], (String) (a[1] == null ? a[0] : a[1]),
(List<String>) a[2], (List<String>) a[3]));
@ -248,7 +242,7 @@ public class CertificateTool extends EnvironmentAwareCommand {
try (Reader reader = Files.newBufferedReader(file)) {
// EMPTY is safe here because we never use namedObject
XContentParser xContentParser = XContentType.YAML.xContent().createParser(NamedXContentRegistry.EMPTY, reader);
return PARSER.parse(xContentParser, new ArrayList<>(), new CertInfoParseContext());
return PARSER.parse(xContentParser, new ArrayList<>(), null);
}
}
@ -632,20 +626,6 @@ public class CertificateTool extends EnvironmentAwareCommand {
}
}
private static class CertInfoParseContext implements ParseFieldMatcherSupplier {
private final ParseFieldMatcher parseFieldMatcher;
CertInfoParseContext() {
this.parseFieldMatcher = ParseFieldMatcher.EMPTY;
}
@Override
public ParseFieldMatcher getParseFieldMatcher() {
return parseFieldMatcher;
}
}
private interface Writer {
void write(ZipOutputStream zipOutputStream, JcaPEMWriter pemWriter) throws Exception;
}

View File

@ -32,7 +32,6 @@ import org.elasticsearch.plugins.ScriptPlugin;
import org.elasticsearch.rest.RestHandler;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.SearchRequestParsers;
import org.elasticsearch.threadpool.ExecutorBuilder;
import org.elasticsearch.threadpool.FixedExecutorBuilder;
import org.elasticsearch.threadpool.ThreadPool;
@ -219,7 +218,7 @@ public class Watcher implements ActionPlugin, ScriptPlugin {
}
public Collection<Object> createComponents(Clock clock, ScriptService scriptService, InternalClient internalClient,
SearchRequestParsers searchRequestParsers, XPackLicenseState licenseState,
XPackLicenseState licenseState,
HttpClient httpClient, HttpRequestTemplate.Parser httpTemplateParser,
ThreadPool threadPool, ClusterService clusterService, CryptoService cryptoService,
NamedXContentRegistry xContentRegistry, Collection<Object> components) {
@ -237,8 +236,7 @@ public class Watcher implements ActionPlugin, ScriptPlugin {
final ConditionRegistry conditionRegistry = new ConditionRegistry(Collections.unmodifiableMap(parsers), clock);
final Map<String, TransformFactory> transformFactories = new HashMap<>();
transformFactories.put(ScriptTransform.TYPE, new ScriptTransformFactory(settings, scriptService));
transformFactories.put(SearchTransform.TYPE, new SearchTransformFactory(settings, internalClient, searchRequestParsers,
xContentRegistry, scriptService));
transformFactories.put(SearchTransform.TYPE, new SearchTransformFactory(settings, internalClient, xContentRegistry, scriptService));
final TransformRegistry transformRegistry = new TransformRegistry(settings, Collections.unmodifiableMap(transformFactories));
final Map<String, ActionFactory> actionFactoryMap = new HashMap<>();
@ -261,7 +259,7 @@ public class Watcher implements ActionPlugin, ScriptPlugin {
final Map<String, InputFactory> inputFactories = new HashMap<>();
inputFactories.put(SearchInput.TYPE,
new SearchInputFactory(settings, internalClient, searchRequestParsers, xContentRegistry, scriptService));
new SearchInputFactory(settings, internalClient, xContentRegistry, scriptService));
inputFactories.put(SimpleInput.TYPE, new SimpleInputFactory(settings));
inputFactories.put(HttpInput.TYPE, new HttpInputFactory(settings, httpClient, templateEngine, httpTemplateParser));
inputFactories.put(NoneInput.TYPE, new NoneInputFactory(settings));
@ -294,7 +292,7 @@ public class Watcher implements ActionPlugin, ScriptPlugin {
final TriggeredWatchStore triggeredWatchStore = new TriggeredWatchStore(settings, watcherClientProxy, triggeredWatchParser);
final WatcherSearchTemplateService watcherSearchTemplateService =
new WatcherSearchTemplateService(settings, scriptService, searchRequestParsers, xContentRegistry);
new WatcherSearchTemplateService(settings, scriptService, xContentRegistry);
final WatchExecutor watchExecutor = getWatchExecutor(threadPool);
final Watch.Parser watchParser = new Watch.Parser(settings, triggerService, registry, inputRegistry, cryptoService, clock);

View File

@ -11,7 +11,6 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.SearchRequestParsers;
import org.elasticsearch.xpack.security.InternalClient;
import org.elasticsearch.xpack.watcher.input.InputFactory;
import org.elasticsearch.xpack.watcher.input.simple.ExecutableSimpleInput;
@ -25,17 +24,17 @@ public class SearchInputFactory extends InputFactory<SearchInput, SearchInput.Re
private final TimeValue defaultTimeout;
private final WatcherSearchTemplateService searchTemplateService;
public SearchInputFactory(Settings settings, InternalClient client, SearchRequestParsers searchRequestParsers,
NamedXContentRegistry xContentRegistry, ScriptService scriptService) {
this(settings, new WatcherClientProxy(settings, client), searchRequestParsers, xContentRegistry, scriptService);
public SearchInputFactory(Settings settings, InternalClient client, NamedXContentRegistry xContentRegistry,
ScriptService scriptService) {
this(settings, new WatcherClientProxy(settings, client), xContentRegistry, scriptService);
}
public SearchInputFactory(Settings settings, WatcherClientProxy client, SearchRequestParsers searchRequestParsers,
NamedXContentRegistry xContentRegistry, ScriptService scriptService) {
public SearchInputFactory(Settings settings, WatcherClientProxy client, NamedXContentRegistry xContentRegistry,
ScriptService scriptService) {
super(Loggers.getLogger(ExecutableSimpleInput.class, settings));
this.client = client;
this.defaultTimeout = settings.getAsTime("xpack.watcher.input.search.default_timeout", null);
this.searchTemplateService = new WatcherSearchTemplateService(settings, scriptService, searchRequestParsers, xContentRegistry);
this.searchTemplateService = new WatcherSearchTemplateService(settings, scriptService, xContentRegistry);
}
@Override

View File

@ -6,7 +6,6 @@
package org.elasticsearch.xpack.watcher.support.search;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.settings.Settings;
@ -17,7 +16,6 @@ import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.script.CompiledScript;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.SearchRequestParsers;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.xpack.watcher.Watcher;
import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext;
@ -34,16 +32,11 @@ import java.util.Map;
public class WatcherSearchTemplateService extends AbstractComponent {
private final ScriptService scriptService;
private final ParseFieldMatcher parseFieldMatcher;
private final SearchRequestParsers searchRequestParsers;
private final NamedXContentRegistry xContentRegistry;
public WatcherSearchTemplateService(Settings settings, ScriptService scriptService, SearchRequestParsers searchRequestParsers,
NamedXContentRegistry xContentRegistry) {
public WatcherSearchTemplateService(Settings settings, ScriptService scriptService, NamedXContentRegistry xContentRegistry) {
super(settings);
this.scriptService = scriptService;
this.searchRequestParsers = searchRequestParsers;
this.parseFieldMatcher = new ParseFieldMatcher(settings);
this.xContentRegistry = xContentRegistry;
}
@ -74,7 +67,7 @@ public class WatcherSearchTemplateService extends AbstractComponent {
BytesReference source = request.getSearchSource();
if (source != null && source.length() > 0) {
try (XContentParser parser = XContentFactory.xContent(source).createParser(xContentRegistry, source)) {
sourceBuilder.parseXContent(new QueryParseContext(parser, parseFieldMatcher));
sourceBuilder.parseXContent(new QueryParseContext(parser));
searchRequest.source(sourceBuilder);
}
}

View File

@ -11,7 +11,6 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.SearchRequestParsers;
import org.elasticsearch.xpack.security.InternalClient;
import org.elasticsearch.xpack.watcher.support.init.proxy.WatcherClientProxy;
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService;
@ -24,17 +23,17 @@ public class SearchTransformFactory extends TransformFactory<SearchTransform, Se
private final TimeValue defaultTimeout;
private final WatcherSearchTemplateService searchTemplateService;
public SearchTransformFactory(Settings settings, InternalClient client, SearchRequestParsers searchRequestParsers,
NamedXContentRegistry xContentRegistry, ScriptService scriptService) {
this(settings, new WatcherClientProxy(settings, client), searchRequestParsers, xContentRegistry, scriptService);
public SearchTransformFactory(Settings settings, InternalClient client, NamedXContentRegistry xContentRegistry,
ScriptService scriptService) {
this(settings, new WatcherClientProxy(settings, client), xContentRegistry, scriptService);
}
public SearchTransformFactory(Settings settings, WatcherClientProxy client, SearchRequestParsers searchRequestParsers,
NamedXContentRegistry xContentRegistry, ScriptService scriptService) {
public SearchTransformFactory(Settings settings, WatcherClientProxy client, NamedXContentRegistry xContentRegistry,
ScriptService scriptService) {
super(Loggers.getLogger(ExecutableSearchTransform.class, settings));
this.client = client;
this.defaultTimeout = settings.getAsTime("xpack.watcher.transform.search.default_timeout", null);
this.searchTemplateService = new WatcherSearchTemplateService(settings, scriptService, searchRequestParsers, xContentRegistry);
this.searchTemplateService = new WatcherSearchTemplateService(settings, scriptService, xContentRegistry);
}
@Override

View File

@ -8,9 +8,6 @@
},
"mappings": {
"_default_": {
"_all": {
"enabled": false
},
"date_detection": false,
"properties": {
"cluster_uuid": {

View File

@ -7,9 +7,6 @@
},
"mappings": {
"_default_": {
"_all": {
"enabled": false
},
"properties": {
"cluster_uuid": {
"type": "keyword"

View File

@ -7,9 +7,6 @@
},
"mappings": {
"_default_": {
"_all": {
"enabled": false
},
"properties": {
"cluster_uuid": {
"type": "keyword"
@ -161,16 +158,20 @@
},
"os": {
"properties": {
"load": {
"cpu": {
"properties": {
"1m": {
"type": "half_float"
},
"5m": {
"type": "half_float"
},
"15m": {
"type": "half_float"
"load_average": {
"properties": {
"1m": {
"type": "half_float"
},
"5m": {
"type": "half_float"
},
"15m": {
"type": "half_float"
}
}
}
}
}

View File

@ -7,9 +7,6 @@
"mappings": {
"event": {
"dynamic" : "strict",
"_all" : {
"enabled" : false
},
"properties": {
"@timestamp": {
"type": "date",

View File

@ -10,9 +10,6 @@
"mappings": {
"triggered_watch": {
"dynamic" : "strict",
"_all" : {
"enabled" : false
},
"properties": {
"trigger_event": {
"type": "object",

View File

@ -40,9 +40,6 @@
}
],
"dynamic": false,
"_all": {
"enabled": false
},
"properties": {
"watch_id": {
"type": "keyword"

View File

@ -9,9 +9,6 @@
"mappings": {
"watch": {
"dynamic" : "strict",
"_all" : {
"enabled" : false
},
"properties": {
"_status": {
"type": "object",

View File

@ -11,6 +11,7 @@ import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.termvectors.MultiTermVectorsResponse;
import org.elasticsearch.action.termvectors.TermVectorsRequest;
@ -26,6 +27,8 @@ import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.children.Children;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortMode;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.xpack.XPackSettings;
@ -283,6 +286,85 @@ public class DocumentLevelSecurityTests extends SecurityIntegTestCase {
assertThat(response.getResponses()[0].getResponse().isExists(), is(false));
}
public void testMSearch() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test1")
.addMapping("type1", "field1", "type=text", "field2", "type=text", "field3", "type=text", "id", "type=integer")
);
assertAcked(client().admin().indices().prepareCreate("test2")
.addMapping("type1", "field1", "type=text", "field2", "type=text", "field3", "type=text", "id", "type=integer")
);
client().prepareIndex("test1", "type1", "1").setSource("field1", "value1", "id", 1).get();
client().prepareIndex("test1", "type1", "2").setSource("field2", "value2", "id", 2).get();
client().prepareIndex("test1", "type1", "3").setSource("field3", "value3", "id", 3).get();
client().prepareIndex("test2", "type1", "1").setSource("field1", "value1", "id", 1).get();
client().prepareIndex("test2", "type1", "2").setSource("field2", "value2", "id", 2).get();
client().prepareIndex("test2", "type1", "3").setSource("field3", "value3", "id", 3).get();
client().admin().indices().prepareRefresh("test1", "test2").get();
MultiSearchResponse response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)))
.prepareMultiSearch()
.add(client().prepareSearch("test1").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.add(client().prepareSearch("test2").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.get();
assertFalse(response.getResponses()[0].isFailure());
assertThat(response.getResponses()[0].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().size(), is(2));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("id"), is(1));
assertFalse(response.getResponses()[1].isFailure());
assertThat(response.getResponses()[1].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().size(), is(2));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("id"), is(1));
response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.prepareMultiSearch()
.add(client().prepareSearch("test1").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.add(client().prepareSearch("test2").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.get();
assertFalse(response.getResponses()[0].isFailure());
assertThat(response.getResponses()[0].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().size(), is(2));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("id"), is(2));
assertFalse(response.getResponses()[1].isFailure());
assertThat(response.getResponses()[1].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().size(), is(2));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("id"), is(2));
response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
.prepareMultiSearch()
.add(client().prepareSearch("test1").setTypes("type1").addSort(SortBuilders.fieldSort("id").sortMode(SortMode.MIN))
.setQuery(QueryBuilders.matchAllQuery()))
.add(client().prepareSearch("test2").setTypes("type1").addSort(SortBuilders.fieldSort("id").sortMode(SortMode.MIN))
.setQuery(QueryBuilders.matchAllQuery()))
.get();
assertFalse(response.getResponses()[0].isFailure());
assertThat(response.getResponses()[0].getResponse().getHits().getTotalHits(), is(2L));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().size(), is(2));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("id"), is(1));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(1).getSource().size(), is(2));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(1).getSource().get("field2"), is("value2"));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(1).getSource().get("id"), is(2));
assertFalse(response.getResponses()[1].isFailure());
assertThat(response.getResponses()[1].getResponse().getHits().getTotalHits(), is(2L));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().size(), is(2));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("id"), is(1));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(1).getSource().size(), is(2));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(1).getSource().get("field2"), is("value2"));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(1).getSource().get("id"), is(2));
}
public void testTVApi() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
.addMapping("type1", "field1", "type=text,term_vector=with_positions_offsets_payloads",

View File

@ -12,6 +12,7 @@ import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.fieldstats.FieldStatsResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.termvectors.MultiTermVectorsResponse;
import org.elasticsearch.action.termvectors.TermVectorsRequest;
@ -20,6 +21,7 @@ import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.IndexModule;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.indices.IndicesRequestCache;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.aggregations.AggregationBuilders;
@ -488,6 +490,155 @@ public class FieldLevelSecurityTests extends SecurityIntegTestCase {
assertThat(response.getResponses()[0].getResponse().getSource().get("field2").toString(), equalTo("value2"));
}
public void testMSearchApi() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test1")
.addMapping("type1", "field1", "type=text", "field2", "type=text", "field3", "type=text")
);
assertAcked(client().admin().indices().prepareCreate("test2")
.addMapping("type1", "field1", "type=text", "field2", "type=text", "field3", "type=text")
);
client().prepareIndex("test1", "type1", "1")
.setSource("field1", "value1", "field2", "value2", "field3", "value3").get();
client().prepareIndex("test2", "type1", "1")
.setSource("field1", "value1", "field2", "value2", "field3", "value3").get();
client().admin().indices().prepareRefresh("test1", "test2").get();
// user1 is granted access to field1 only
MultiSearchResponse response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)))
.prepareMultiSearch()
.add(client().prepareSearch("test1").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.add(client().prepareSearch("test2").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.get();
assertFalse(response.getResponses()[0].isFailure());
assertThat(response.getResponses()[0].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().size(), is(1));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[1].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().size(), is(1));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
// user2 is granted access to field2 only
response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.prepareMultiSearch()
.add(client().prepareSearch("test1").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.add(client().prepareSearch("test2").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.get();
assertFalse(response.getResponses()[0].isFailure());
assertThat(response.getResponses()[0].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().size(), is(1));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
assertThat(response.getResponses()[1].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().size(), is(1));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
// user3 is granted access to field1 and field2
response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
.prepareMultiSearch()
.add(client().prepareSearch("test1").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.add(client().prepareSearch("test2").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.get();
assertFalse(response.getResponses()[0].isFailure());
assertThat(response.getResponses()[0].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().size(), is(2));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
assertThat(response.getResponses()[1].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().size(), is(2));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
// user4 is granted access to no fields, so the search response does say the doc exist, but no fields are returned
response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD)))
.prepareMultiSearch()
.add(client().prepareSearch("test1").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.add(client().prepareSearch("test2").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.get();
assertFalse(response.getResponses()[0].isFailure());
assertThat(response.getResponses()[0].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().size(), is(0));
assertThat(response.getResponses()[1].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().size(), is(0));
// user5 has no field level security configured, so all fields are returned
response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD)))
.prepareMultiSearch()
.add(client().prepareSearch("test1").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.add(client().prepareSearch("test2").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.get();
assertFalse(response.getResponses()[0].isFailure());
assertThat(response.getResponses()[0].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().size(), is(3));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field3"), is("value3"));
assertThat(response.getResponses()[1].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().size(), is(3));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field3"), is("value3"));
// user6 has access to field*
response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD)))
.prepareMultiSearch()
.add(client().prepareSearch("test1").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.add(client().prepareSearch("test2").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.get();
assertFalse(response.getResponses()[0].isFailure());
assertThat(response.getResponses()[0].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().size(), is(3));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field3"), is("value3"));
assertThat(response.getResponses()[1].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().size(), is(3));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field3"), is("value3"));
// user7 has roles with field level security and without field level security
response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user7", USERS_PASSWD)))
.prepareMultiSearch()
.add(client().prepareSearch("test1").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.add(client().prepareSearch("test2").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.get();
assertFalse(response.getResponses()[0].isFailure());
assertThat(response.getResponses()[0].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().size(), is(3));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field3"), is("value3"));
assertThat(response.getResponses()[1].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().size(), is(3));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field3"), is("value3"));
// user8 has roles with field level security with access to field1 and field2
response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user8", USERS_PASSWD)))
.prepareMultiSearch()
.add(client().prepareSearch("test1").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.add(client().prepareSearch("test2").setTypes("type1").setQuery(QueryBuilders.matchAllQuery()))
.get();
assertFalse(response.getResponses()[0].isFailure());
assertThat(response.getResponses()[0].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().size(), is(2));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[0].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
assertThat(response.getResponses()[1].getResponse().getHits().getTotalHits(), is(1L));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().size(), is(2));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field1"), is("value1"));
assertThat(response.getResponses()[1].getResponse().getHits().getAt(0).getSource().get("field2"), is("value2"));
}
public void testFieldStatsApi() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
.addMapping("type1", "field1", "type=text", "field2", "type=text", "field3", "type=text")

View File

@ -9,9 +9,7 @@ import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.Version;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.PlainActionFuture;
import org.elasticsearch.cluster.ClusterChangedEvent;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.ClusterStateUpdateTask;
import org.elasticsearch.cluster.LocalClusterUpdateTask;
import org.elasticsearch.cluster.NodeConnectionsService;
import org.elasticsearch.cluster.block.ClusterBlocks;
@ -44,7 +42,6 @@ import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
@ -101,12 +98,12 @@ public class TransportMonitoringBulkActionTests extends ESTestCase {
Version.CURRENT));
clusterService.setNodeConnectionsService(new NodeConnectionsService(Settings.EMPTY, null, null) {
@Override
public void connectToNodes(List<DiscoveryNode> addedNodes) {
public void connectToNodes(Iterable<DiscoveryNode> discoveryNodes) {
// skip
}
@Override
public void disconnectFromNodes(List<DiscoveryNode> removedNodes) {
public void disconnectFromNodesExcept(Iterable<DiscoveryNode> nodesToKeep) {
// skip
}
});

View File

@ -185,9 +185,6 @@ public class LocalExporterTemplateTests extends MonitoringIntegTestCase {
.endObject()
.startObject("mappings")
.startObject("_default_")
.startObject("_all")
.field("enabled", false)
.endObject()
.field("date_detection", false)
.startObject("properties")
.startObject("cluster_uuid")

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.xpack.security.action.filter;
import org.apache.lucene.util.SetOnce;
import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.ActionRequest;
@ -60,6 +61,7 @@ public class SecurityActionFilterTests extends ESTestCase {
private AuditTrailService auditTrail;
private XPackLicenseState licenseState;
private SecurityActionFilter filter;
private ThreadContext threadContext;
private boolean failDestructiveOperations;
@Before
@ -72,14 +74,17 @@ public class SecurityActionFilterTests extends ESTestCase {
when(licenseState.isAuthAllowed()).thenReturn(true);
when(licenseState.isStatsAndHealthAllowed()).thenReturn(true);
ThreadPool threadPool = mock(ThreadPool.class);
when(threadPool.getThreadContext()).thenReturn(new ThreadContext(Settings.EMPTY));
threadContext = new ThreadContext(Settings.EMPTY);
when(threadPool.getThreadContext()).thenReturn(threadContext);
failDestructiveOperations = randomBoolean();
Settings settings = Settings.builder()
.put(DestructiveOperations.REQUIRES_NAME_SETTING.getKey(), failDestructiveOperations).build();
DestructiveOperations destructiveOperations = new DestructiveOperations(settings,
new ClusterSettings(settings, Collections.singleton(DestructiveOperations.REQUIRES_NAME_SETTING)));
SecurityContext securityContext = new SecurityContext(settings, threadContext, cryptoService);
filter = new SecurityActionFilter(Settings.EMPTY, authcService, authzService, cryptoService, auditTrail,
licenseState, new HashSet<>(), threadPool, mock(SecurityContext.class), destructiveOperations);
licenseState, new HashSet<>(), threadPool, securityContext, destructiveOperations);
}
public void testApply() throws Exception {
@ -108,6 +113,81 @@ public class SecurityActionFilterTests extends ESTestCase {
verify(chain).proceed(eq(task), eq("_action"), eq(request), isA(ContextPreservingActionListener.class));
}
public void testApplyRestoresThreadContext() throws Exception {
ActionRequest request = mock(ActionRequest.class);
ActionListener listener = mock(ActionListener.class);
ActionFilterChain chain = mock(ActionFilterChain.class);
Task task = mock(Task.class);
User user = new User("username", "r1", "r2");
Authentication authentication = new Authentication(user, new RealmRef("test", "test", "foo"), null);
doAnswer((i) -> {
ActionListener callback =
(ActionListener) i.getArguments()[3];
assertNull(threadContext.getTransient(Authentication.AUTHENTICATION_KEY));
threadContext.putTransient(Authentication.AUTHENTICATION_KEY, authentication);
callback.onResponse(authentication);
return Void.TYPE;
}).when(authcService).authenticate(eq("_action"), eq(request), eq(SystemUser.INSTANCE), any(ActionListener.class));
final Role empty = Role.EMPTY;
doAnswer((i) -> {
ActionListener callback =
(ActionListener) i.getArguments()[1];
assertEquals(authentication, threadContext.getTransient(Authentication.AUTHENTICATION_KEY));
callback.onResponse(empty);
return Void.TYPE;
}).when(authzService).roles(any(User.class), any(ActionListener.class));
doReturn(request).when(spy(filter)).unsign(user, "_action", request);
assertNull(threadContext.getTransient(Authentication.AUTHENTICATION_KEY));
filter.apply(task, "_action", request, listener, chain);
assertNull(threadContext.getTransient(Authentication.AUTHENTICATION_KEY));
verify(authzService).authorize(authentication, "_action", request, empty, null);
verify(chain).proceed(eq(task), eq("_action"), eq(request), isA(ContextPreservingActionListener.class));
}
public void testApplyAsSystemUser() throws Exception {
ActionRequest request = mock(ActionRequest.class);
ActionListener listener = mock(ActionListener.class);
User user = new User("username", "r1", "r2");
Authentication authentication = new Authentication(user, new RealmRef("test", "test", "foo"), null);
SetOnce<Authentication> authenticationSetOnce = new SetOnce<>();
ActionFilterChain chain = (task, action, request1, listener1) -> {
authenticationSetOnce.set(threadContext.getTransient(Authentication.AUTHENTICATION_KEY));
};
Task task = mock(Task.class);
final boolean hasExistingAuthentication = randomBoolean();
final String action = "internal:foo";
if (hasExistingAuthentication) {
threadContext.putTransient(Authentication.AUTHENTICATION_KEY, authentication);
threadContext.putTransient(AuthorizationService.ORIGINATING_ACTION_KEY, "indices:foo");
} else {
assertNull(threadContext.getTransient(Authentication.AUTHENTICATION_KEY));
}
doAnswer((i) -> {
ActionListener callback =
(ActionListener) i.getArguments()[3];
callback.onResponse(threadContext.getTransient(Authentication.AUTHENTICATION_KEY));
return Void.TYPE;
}).when(authcService).authenticate(eq(action), eq(request), eq(SystemUser.INSTANCE), any(ActionListener.class));
doReturn(request).when(spy(filter)).unsign(user, action, request);
doAnswer((i) -> {
String text = (String) i.getArguments()[0];
return text;
}).when(cryptoService).sign(any(String.class));
filter.apply(task, action, request, listener, chain);
if (hasExistingAuthentication) {
assertEquals(authentication, threadContext.getTransient(Authentication.AUTHENTICATION_KEY));
} else {
assertNull(threadContext.getTransient(Authentication.AUTHENTICATION_KEY));
}
assertNotNull(authenticationSetOnce.get());
assertNotEquals(authentication, authenticationSetOnce.get());
assertEquals(SystemUser.INSTANCE, authenticationSetOnce.get().getUser());
}
public void testApplyDestructiveOperations() throws Exception {
ActionRequest request = new MockIndicesRequest(
IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean()),

View File

@ -7,6 +7,7 @@ package org.elasticsearch.xpack.watcher.actions.throttler;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.xpack.common.http.HttpMethod;
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.common.text.TextTemplate;
@ -40,8 +41,8 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.indexAction;
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.loggingAction;
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.webhookAction;
import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBuilder;
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.interval;
@ -287,8 +288,21 @@ public class ActionThrottleTests extends AbstractWatcherIntegrationTestCase {
}, 20, TimeUnit.SECONDS);
}
@AwaitsFix(bugUrl = "https://github.com/elastic/x-pack/issues/4561")
public void testFailingActionDoesGetThrottled() throws Exception {
// create a mapping with a wrong @timestamp field, so that the index action of the watch below will fail
String mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject("bar")
.startObject("properties")
.startObject("@timestamp")
.field("type", "integer")
.endObject()
.endObject()
.endObject()
.endObject().string();
client().admin().indices().prepareCreate("foo").addMapping("bar", mapping).get();
TimeValue throttlePeriod = new TimeValue(60, TimeUnit.MINUTES);
watcherClient().preparePutWatch("_id").setSource(watchBuilder()
@ -296,8 +310,7 @@ public class ActionThrottleTests extends AbstractWatcherIntegrationTestCase {
new IntervalSchedule.Interval(60, IntervalSchedule.Interval.Unit.MINUTES))))
.defaultThrottlePeriod(throttlePeriod)
.addAction("logging", loggingAction("test out"))
// no DNS resolution here please
.addAction("failing_hook", webhookAction(HttpRequestTemplate.builder("http://127.0.0.1/foobar", 80))))
.addAction("failing_hook", indexAction("foo", "bar").setExecutionTimeField("@timestamp")))
.get();
refresh(Watch.INDEX);

View File

@ -17,7 +17,6 @@ import org.elasticsearch.plugins.ScriptPlugin;
import org.elasticsearch.script.MockMustacheScriptEngine;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.SearchRequestParsers;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
@ -144,9 +143,8 @@ public class SearchInputTests extends ESIntegTestCase {
XContentParser parser = createParser(builder);
parser.nextToken();
SearchRequestParsers searchParsers = new SearchRequestParsers();
SearchInputFactory factory = new SearchInputFactory(Settings.EMPTY, WatcherClientProxy.of(client()),
searchParsers, xContentRegistry(), scriptService());
xContentRegistry(), scriptService());
SearchInput searchInput = factory.parseInput("_id", parser);
assertEquals(SearchInput.TYPE, searchInput.type());
@ -157,7 +155,6 @@ public class SearchInputTests extends ESIntegTestCase {
String master = internalCluster().getMasterName();
return new WatcherSearchTemplateService(internalCluster().clusterService(master).getSettings(),
internalCluster().getInstance(ScriptService.class, master),
internalCluster().getInstance(SearchRequestParsers.class, master),
internalCluster().getInstance(NamedXContentRegistry.class, master)
);
}

View File

@ -21,7 +21,6 @@ import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.search.SearchRequestParsers;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
@ -212,9 +211,8 @@ public class SearchTransformTests extends ESIntegTestCase {
XContentParser parser = createParser(builder);
parser.nextToken();
SearchRequestParsers searchRequestParsers = internalCluster().getInstance(SearchRequestParsers.class);
SearchTransformFactory transformFactory = new SearchTransformFactory(Settings.EMPTY, WatcherClientProxy.of(client()),
searchRequestParsers, xContentRegistry(), scriptService());
xContentRegistry(), scriptService());
ExecutableSearchTransform executable = transformFactory.parseExecutable("_id", parser);
assertThat(executable, notNullValue());
@ -284,7 +282,6 @@ public class SearchTransformTests extends ESIntegTestCase {
String master = internalCluster().getMasterName();
return new WatcherSearchTemplateService(internalCluster().clusterService(master).getSettings(),
internalCluster().getInstance(ScriptService.class, master),
internalCluster().getInstance(SearchRequestParsers.class, master),
xContentRegistry()
);
}

View File

@ -23,7 +23,6 @@ import org.elasticsearch.index.query.ScriptQueryBuilder;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.SearchRequestParsers;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.common.http.HttpClient;
import org.elasticsearch.xpack.common.http.HttpMethod;
@ -288,9 +287,7 @@ public class WatchTests extends ESTestCase {
ActionRegistry actionRegistry = registry(Collections.emptyList(), conditionRegistry, transformRegistry);
Watch.Parser watchParser = new Watch.Parser(settings, triggerService, actionRegistry, inputRegistry, null, Clock.systemUTC());
SearchRequestParsers searchParsers = new SearchRequestParsers();
WatcherSearchTemplateService searchTemplateService = new WatcherSearchTemplateService(settings, scriptService, searchParsers,
xContentRegistry());
WatcherSearchTemplateService searchTemplateService = new WatcherSearchTemplateService(settings, scriptService, xContentRegistry());
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
@ -409,8 +406,7 @@ public class WatchTests extends ESTestCase {
Map<String, InputFactory> parsers = new HashMap<>();
switch (inputType) {
case SearchInput.TYPE:
SearchRequestParsers searchParsers = new SearchRequestParsers();
parsers.put(SearchInput.TYPE, new SearchInputFactory(settings, client, searchParsers, xContentRegistry(), scriptService));
parsers.put(SearchInput.TYPE, new SearchInputFactory(settings, client, xContentRegistry(), scriptService));
return new InputRegistry(Settings.EMPTY, parsers);
default:
parsers.put(SimpleInput.TYPE, new SimpleInputFactory(settings));
@ -457,10 +453,9 @@ public class WatchTests extends ESTestCase {
}
private TransformRegistry transformRegistry() {
SearchRequestParsers searchParsers = new SearchRequestParsers();
Map<String, TransformFactory> factories = new HashMap<>();
factories.put(ScriptTransform.TYPE, new ScriptTransformFactory(settings, scriptService));
factories.put(SearchTransform.TYPE, new SearchTransformFactory(settings, client, searchParsers, xContentRegistry(), scriptService));
factories.put(SearchTransform.TYPE, new SearchTransformFactory(settings, client, xContentRegistry(), scriptService));
return new TransformRegistry(Settings.EMPTY, unmodifiableMap(factories));
}