Merge branch 'master' into feature/sql

Original commit: elastic/x-pack-elasticsearch@ccc2fc708e
This commit is contained in:
Nik Everett 2017-11-28 13:24:36 -05:00
commit 0cc153f6d3
71 changed files with 454 additions and 1622 deletions

View File

@ -51,7 +51,6 @@ subprojects {
additionalLicense 'ESCON', 'Elasticsearch Confidential', 'ELASTICSEARCH CONFIDENTIAL'
}
ext.projectSubstitutions += [ "org.elasticsearch.plugin:x-pack-api:${version}": ':x-pack-elasticsearch:plugin']
ext.projectSubstitutions += [ "org.elasticsearch:x-pack-client-api-objects:${version}": ':x-pack-elasticsearch:client:client-api-objects']
for (final Version version : versionCollection.versionsIndexCompatibleWithCurrent) {
if (version.branch != null) {

View File

View File

@ -1,4 +0,0 @@
# Client API objects
This is a common dependency of the `xpack` and `transport-client` projects so
they can share the same `Request` and `Response` objects.

View File

@ -1,10 +0,0 @@
apply plugin: 'elasticsearch.build'
dependencies {
provided "org.elasticsearch:elasticsearch:${version}"
}
archivesBaseName = 'x-pack-client-api-objects'
// TODO: enable this once we have tests
test.enabled=false

View File

@ -29,7 +29,6 @@ buildRestTests.expectedUnconvertedCandidates = [
'en/security/tribe-clients-integrations/beats.asciidoc',
'en/security/tribe-clients-integrations/http.asciidoc',
'en/security/tribe-clients-integrations/monitoring.asciidoc',
'en/security/tribe-clients-integrations/cross-cluster.asciidoc',
'en/security/authorization/custom-roles-provider.asciidoc',
'en/watcher/actions/email.asciidoc',
'en/watcher/actions/hipchat.asciidoc',
@ -75,10 +74,7 @@ buildRestTests.expectedUnconvertedCandidates = [
'en/rest-api/ml/get-datafeed-stats.asciidoc',
'en/rest-api/ml/get-job-stats.asciidoc',
'en/rest-api/ml/get-record.asciidoc',
'en/rest-api/ml/open-job.asciidoc',
'en/rest-api/ml/preview-datafeed.asciidoc',
'en/rest-api/ml/start-datafeed.asciidoc',
'en/rest-api/ml/stop-datafeed.asciidoc',
'en/rest-api/ml/update-datafeed.asciidoc',
'en/rest-api/ml/update-job.asciidoc',
'en/rest-api/ml/update-snapshot.asciidoc',
@ -145,6 +141,9 @@ Closure waitWithAuth = { NodeInfo node, AntBuilder ant ->
integTestCluster {
plugin ':x-pack-elasticsearch:plugin'
setting 'xpack.security.authc.token.enabled', 'true'
// Disable monitoring exporters for the docs tests
setting 'xpack.monitoring.exporters._local.type', 'local'
setting 'xpack.monitoring.exporters._local.enabled', 'false'
setupCommand 'setupTestAdmin',
'bin/x-pack/users', 'useradd', 'test_admin', '-p', 'x-pack-test-password', '-r', 'superuser'
waitCondition = waitWithAuth
@ -323,3 +322,104 @@ setups['server_metrics_job'] = '''
}
}
'''
setups['server_metrics_openjob'] = '''
- do:
indices.create:
index: server-metrics
body:
settings:
number_of_shards: 1
number_of_replicas: 0
mappings:
metric:
properties:
timestamp:
type: date
total:
type: long
- do:
xpack.ml.put_job:
job_id: "total-requests"
body: >
{
"description" : "Total sum of requests",
"analysis_config" : {
"bucket_span":"10m",
"detectors" :[
{
"detector_description": "Sum of total",
"function": "sum",
"field_name": "total"
}
]},
"data_description" : {
"time_field":"timestamp",
"time_format": "epoch_ms"
}
}
- do:
xpack.ml.put_datafeed:
datafeed_id: "datafeed-total-requests"
body: >
{
"job_id":"total-requests",
"indexes":"server-metrics",
"types":"metric"
}
- do:
xpack.ml.open_job:
job_id: "total-requests"
'''
setups['server_metrics_startdf'] = '''
- do:
indices.create:
index: server-metrics
body:
settings:
number_of_shards: 1
number_of_replicas: 0
mappings:
metric:
properties:
timestamp:
type: date
total:
type: long
- do:
xpack.ml.put_job:
job_id: "total-requests"
body: >
{
"description" : "Total sum of requests",
"analysis_config" : {
"bucket_span":"10m",
"detectors" :[
{
"detector_description": "Sum of total",
"function": "sum",
"field_name": "total"
}
]},
"data_description" : {
"time_field":"timestamp",
"time_format": "epoch_ms"
}
}
- do:
xpack.ml.put_datafeed:
datafeed_id: "datafeed-total-requests"
body: >
{
"job_id":"total-requests",
"indexes":"server-metrics",
"types":"metric"
}
- do:
xpack.ml.open_job:
job_id: "total-requests"
- do:
xpack.ml.start_datafeed:
datafeed_id: "datafeed-total-requests"
'''

View File

@ -8,6 +8,7 @@
{xpack} includes commands that help you configure security:
* <<certgen>>
* <<migrate-tool>>
* <<setup-passwords>>
* <<syskeygen>>
* <<users-command>>
@ -15,6 +16,7 @@
--
include::certgen.asciidoc[]
include::migrate-tool.asciidoc[]
include::setup-passwords.asciidoc[]
include::syskeygen.asciidoc[]
include::users-command.asciidoc[]

View File

@ -1,28 +1,84 @@
[role="xpack"]
[[migrate-tool]]
==== Migrating File-based Users and Roles to the Native Realm
== migrate
From 5.0 onward, you should use the `native` realm to manage roles and local
users. To migrate existing file-based users and roles to the native realm, use
the `migrate` tool that's included with the X-Pack plugin.
The `migrate` command migrates existing file-based users and roles to the native
realm. From 5.0 onward, you should use the `native` realm to manage roles and
local users.
[float]
=== Synopsis
[source,shell]
--------------------------------------------------
bin/x-pack/migrate
(native (-U, --url <url>)
[-h, --help] [-E <KeyValuePair>]
[-n, --users <uids>] [-r, --roles <roles>]
[-u, --username <uid>] [-p, --password <password>]
[-s, --silent] [-v, --verbose])
--------------------------------------------------
[float]
=== Description
NOTE: When migrating from Shield 2.x, the `migrate` tool should be run prior
to upgrading to ensure all roles can be migrated as some may be in a deprecated
format that {xpack} cannot read. The `migrate` tool is available in Shield
2.4.0 and higher.
The `migrate` tool loads the existing file-based users and roles and calls the
user and roles APIs to add them to the native realm. You can migrate all users
and roles, or specify the ones you want to migrate. Users and roles that
already exist in the `native` realm are not replaced or overridden. If
the names you specify with the `--users` and `--roles` options don't
The `migrate` tool loads the existing file-based users and roles and calls the
user and roles APIs to add them to the native realm. You can migrate all users
and roles, or specify the ones you want to migrate. Users and roles that
already exist in the `native` realm are not replaced or overridden. If
the names you specify with the `--users` and `--roles` options don't
exist in the `file` realm, they are skipped.
[float]
[[migrate-tool-options]]
=== Parameters
The `native` subcommand supports the following options:
`-E <KeyValuePair>`::
Configures a setting.
`-h, --help`::
Returns all of the command parameters.
`-n`, `--users`::
Comma-separated list of the users that you want to migrate. If this parameter is
not specified, all users are migrated.
`-p`, `--password`::
Password to use for authentication with {es}.
//TBD: What is the default if this isn't specified?
`-r`, `--roles`::
Comma-separated list of the roles that you want to migrate. If this parameter is
not specified, all roles are migrated.
`-s, --silent`:: Shows minimal output.
`-U`, `--url`::
Endpoint URL of the {es} cluster to which you want to migrate the
file-based users and roles. This parameter is required.
`-u`, `--username`::
Username to use for authentication with {es}.
//TBD: What is the default if this isn't specified?
`-v, --verbose`:: Shows verbose output.
[float]
=== Examples
Run the migrate tool after you install the X-Pack plugin. For example:
[source, sh]
----------------------------------------------------------------------
$ bin/x-pack/migrate native -U http://localhost:9200 -u elastic -p x-pack-test-password
-n lee,foo -r role1,role2,role3,role4,foo
$ bin/x-pack/migrate native -U http://localhost:9200 -u elastic
-p x-pack-test-password -n lee,foo -r role1,role2,role3,role4,foo
starting migration of users and roles...
importing users from [/home/es/config/shield/users]...
found existing users: [test_user, joe3, joe2]
@ -30,9 +86,9 @@ migrating user [lee]
{"user":{"created":true}}
no user [foo] found, skipping
importing roles from [/home/es/config/shield/roles.yml]...
found existing roles: [marvel_user, role_query_fields, admin_role, role3, admin,
remote_marvel_agent, power_user, role_new_format_name_array, role_run_as,
logstash, role_fields, role_run_as1, role_new_format, kibana4_server, user,
found existing roles: [marvel_user, role_query_fields, admin_role, role3, admin,
remote_marvel_agent, power_user, role_new_format_name_array, role_run_as,
logstash, role_fields, role_run_as1, role_new_format, kibana4_server, user,
transport_client, role1.ab, role_query]
migrating role [role1]
{"role":{"created":true}}
@ -43,31 +99,11 @@ no role [foo] found, skipping
users and roles imported.
----------------------------------------------------------------------
[[migrate-tool-options]]
The `native` subcommand supports the following options:
`-U`, `--url`::
Endpoint URL of the Elasticsearch cluster to which you want to migrate the
file-based users and roles. Required.
`-u`, `--username`::
Username to use for authentication.
`-p`, `--password`::
Password to use for authentication.
`-n`, `--users`::
Comma-separated list of the users you want to migrate. If not specified, all
users are migrated.
`-r`, `--roles`::
Comma-separated list of the roles you want to migrate. If not specified, all
roles are migrated.
Additionally, the `-E` flag can be used to specify additional settings. For example
to specify a different configuration directory, the command would look like:
[source, sh]
----------------------------------------------------------------------
$ bin/x-pack/migrate native -U http://localhost:9200 -u elastic -p x-pack-test-password --path.conf /etc/elasticsearch
$ bin/x-pack/migrate native -U http://localhost:9200 -u elastic
-p x-pack-test-password -E path.conf=/etc/elasticsearch
----------------------------------------------------------------------

View File

@ -38,27 +38,19 @@ forecast. For more information about this property, see <<ml-job-resource>>.
(string) Identifier for the job.
==== Query Parameters
==== Request Parameters
`duration`::
(time units) A period of time that indicates how far into the future to
forecast. For example, `2w` corresponds to 2 weeks. The forecast starts at the
forecast. For example, `30d` corresponds to 30 days. The forecast starts at the
last record that was processed. For more information about time units, see
<<time-units>>.
////
//Not a supported feature:
`end`::
(string) The time that the forecast should end. The string can contain
formatted dates, a number representing milliseconds since the epoch, or a
number representing seconds since the epoch. It can also contain
<<date-math,date math expressions>>. The default value is one day after
the last record that was processed.
NOTE: You can specify either the `duration` or `end` parameter; if you specify
both, an error occurs.
////
`expires_in`::
(time units) The period of time that forecast results are retained.
After a forecast expires, the results are deleted. The default value is 14 days.
If set to a value of `0`, the forecast is never automatically deleted.
For more information about time units, see <<time-units>>.
==== Authorization

View File

@ -13,8 +13,6 @@ A job can be opened and closed multiple times throughout its lifecycle.
==== Description
A job must be open in order to it to accept and analyze data.
When you open a new job, it starts with an empty model.
When you open an existing job, the most recent model state is automatically loaded.
@ -39,22 +37,22 @@ The job is ready to resume its analysis from where it left off, once new data is
You must have `manage_ml`, or `manage` cluster privileges to use this API.
For more information, see
{xpack-ref}/security-privileges.html[Security Privileges].
//<<privileges-list-cluster>>.
==== Examples
The following example opens the `event_rate` job and sets an optional property:
The following example opens the `total-requests` job and sets an optional
property:
[source,js]
--------------------------------------------------
POST _xpack/ml/anomaly_detectors/event_rate/_open
POST _xpack/ml/anomaly_detectors/total-requests/_open
{
"timeout": "35m"
}
--------------------------------------------------
// CONSOLE
// TEST[skip:todo]
// TEST[setup:server_metrics_job]
When the job opens, you receive the following results:
[source,js]
@ -63,3 +61,5 @@ When the job opens, you receive the following results:
"opened": true
}
----
//CONSOLE
// TESTRESPONSE

View File

@ -84,13 +84,13 @@ The following example starts the `datafeed-it-ops-kpi` {dfeed}:
[source,js]
--------------------------------------------------
POST _xpack/ml/datafeeds/datafeed-it-ops-kpi/_start
POST _xpack/ml/datafeeds/datafeed-total-requests/_start
{
"start": "2017-04-07T18:22:16Z"
}
--------------------------------------------------
// CONSOLE
// TEST[skip:todo]
// TEST[setup:server_metrics_openjob]
When the {dfeed} starts, you receive the following results:
[source,js]
@ -99,3 +99,5 @@ When the {dfeed} starts, you receive the following results:
"started": true
}
----
// CONSOLE
// TESTRESPONSE

View File

@ -50,17 +50,17 @@ For more information, see
==== Examples
The following example stops the `datafeed-it-ops-kpi` {dfeed}:
The following example stops the `datafeed-total-requests` {dfeed}:
[source,js]
--------------------------------------------------
POST _xpack/ml/datafeeds/datafeed-it-ops-kpi/_stop
POST _xpack/ml/datafeeds/datafeed-total-requests/_stop
{
"timeout": "30s"
}
--------------------------------------------------
// CONSOLE
// TEST[skip:todo]
// TEST[setup:server_metrics_startdf]
When the {dfeed} stops, you receive the following results:
[source,js]
@ -69,3 +69,5 @@ When the {dfeed} stops, you receive the following results:
"stopped": true
}
----
// CONSOLE
// TESTRESPONSE

View File

@ -92,7 +92,7 @@ You manage users in the `native` realm through the
[[migrating-from-file]]
NOTE: To migrate file-based users to the `native` realm, use the
<<migrate-tool, migrate>> tool.
{ref}/migrate-tool.html[migrate tool].
[float]
[[native-add]]

View File

@ -17,9 +17,8 @@ is allowed to access.
[WARNING]
This feature was added as Beta in Elasticsearch `v5.3` with further
improvements made in 5.4 and 5.5. It requires gateway eligible nodes to be on
`v5.5` onwards.
This feature was added as Beta in {es} `v5.3` with further improvements made in
5.4 and 5.5. It requires gateway eligible nodes to be on `v5.5` onwards.
To use cross cluster search with secured clusters:
@ -42,6 +41,7 @@ To use cross cluster search with secured clusters:
For example, the following configuration adds two remote clusters
to the local cluster:
+
--
[source,js]
-----------------------------------------------------------
PUT _cluster/settings
@ -60,6 +60,8 @@ PUT _cluster/settings
}
}
-----------------------------------------------------------
// CONSOLE
--
* On the local cluster, ensure that users are assigned to (at least) one role
that exists on the remote clusters. On the remote clusters, use that role
@ -75,13 +77,14 @@ First, enable cluster `one` to perform cross cluster search on remote cluster
[source,js]
-----------------------------------------------------------
PUT _cluster_settings
PUT _cluster/settings
{
"persistent": {
"search.remote.two.seeds": [ "10.0.2.1:9300" ]
"search.remote.cluster_two.seeds": [ "10.0.2.1:9300" ]
}
}
-----------------------------------------------------------
// CONSOLE
Next, set up a role called `cluster_two_logs` on both cluster `one` and
cluster `two`.
@ -94,6 +97,7 @@ POST /_xpack/security/role/cluster_two_logs
{
}
-----------------------------------------------------------
// CONSOLE
On cluster `two`, this role allows the user to query local indices called
`logs-` from a remote cluster:
@ -118,6 +122,7 @@ POST /_xpack/security/role/cluster_two_logs
]
}
-----------------------------------------------------------
// CONSOLE
Finally, create a user on cluster `one` and apply the `cluster_two_logs` role:
@ -132,6 +137,7 @@ POST /_xpack/security/user/alice
"enabled": true
}
-----------------------------------------------------------
// CONSOLE
With all of the above setup, the user `alice` is able to search indices in
cluster `two` as follows:
@ -145,6 +151,8 @@ GET two:logs-2017.04/_search <1>
}
}
-----------------------------------------------------------
// CONSOLE
// TEST[skip:todo]
//TBD: Is there a missing description of the <1> callout above?
include::{xkb-repo-dir}/security/cross-cluster-kibana.asciidoc[]

View File

@ -39,7 +39,6 @@ dependencyLicenses {
mapping from: /http.*/, to: 'httpclient' // pulled in by rest client
mapping from: /commons-.*/, to: 'commons' // pulled in by rest client
ignoreSha 'elasticsearch-rest-client'
ignoreSha 'x-pack-client-api-objects'
ignoreSha 'transport-netty4'
ignoreSha 'tribe'
ignoreSha 'server'
@ -71,9 +70,6 @@ dependencies {
// CLI deps
compile project(path: ':core:cli', configuration: 'runtime')
// Request and Response objects
compile "org.elasticsearch:x-pack-client-api-objects:${version}"
// security deps
compile project(path: ':modules:transport-netty4', configuration: 'runtime')
compile 'com.unboundid:unboundid-ldapsdk:3.2.0'

View File

@ -1,120 +0,0 @@
COMMERCIAL SOFTWARE END USER LICENSE AGREEMENT
READ THIS COMMERCIAL SOFTWARE END USER LICENSE AGREEMENT CAREFULLY, WHICH CONSTITUTES A LEGALLY BINDING AGREEMENT AND GOVERNS YOUR USE OF ELASTICS PROPRIETARY SOFTWARE. BY INSTALLING AND/OR USING SUCH SOFTWARE, YOU ARE INDICATING THAT YOU AGREE TO THE TERMS AND CONDITIONS SET FORTH IN THIS AGREEMENT. IF YOU DO NOT AGREE WITH SUCH TERMS AND CONDITIONS, YOU MAY NOT INSTALL OR USE ANY OF THE SOFTWARE. IF YOU ARE INSTALLING OR USING THE SOFTWARE ON BEHALF OF YOUR EMPLOYER OR ANOTHER ENTITY, YOU REPRESENT AND WARRANT THAT YOU HAVE THE ACTUAL AUTHORITY TO AGREE TO THE TERMS AND CONDITIONS ON BEHALF OF SUCH EMPLOYER OR OTHER ENTITY.
This COMMERCIAL SOFTWARE END USER LICENSE AGREEMENT (this “Agreement") is entered into by and between the applicable Elastic entity referenced in Attachment 1 hereto (“Elastic”) and the person, or entity on behalf of whom you are acting, as applicable (“You” or “Customer”) that has downloaded any of Elastics proprietary software to which this Agreement is attached or in connection with which this Agreement is presented to You (collectively, the “Software”). This Agreement is effective upon the earliest date of the commencement of any License granted pursuant to Section 1.1. below (as applicable, the “Effective Date”).
1. SOFTWARE LICENSE AND RESTRICTIONS
1.1 License Grants.
(a) Trial Version License. Subject to the terms and conditions of this Agreement, Elastic agrees to grant, and does hereby grant to You, for a period of thirty (30) days from the date on which You first install the Software (the “Trial Term”), a License to use the Eligible Features and Functions of the Software that are applicable to the Trial Version of the Software.   You understand and agree that upon the expiration of a Trial Term, You will no longer be able to use the Software, unless you either (i) purchase a Subscription, in which case You will receive a License under Section 1.1(b) below to use the Eligible Features and Functions of the Software that are applicable to the Subscription level that You purchase, (ii) complete the Registration of Your use of the Software with Elastic, in which case, if available, You will receive a License under Section 1.1(c) below to the Basic Version of the Software or (iii) obtain from Elastic written consent (e-mail sufficient) to extend the Trial Term, which may be granted by Elastic in its sole and absolute discretion.
(b) Subscription License. If you enter into a Subscription Agreement with Elastic, then, subject to the terms and conditions of this Agreement and complete payment of any and all applicable Subscription fees, Elastic agrees to grant, and does hereby grant to You during the applicable Subscription Term, and for the restricted scope of this Agreement, a License to use the Eligible Features and Functions of the Software that are applicable to the Subscription level that You have purchased, for the number of Nodes and for the specific Project for which you have purchased a Subscription. The level of Subscription, the number of Nodes and specific Project for which you have purchased such Subscription, are set forth on the applicable ordering document entered into by Elastic and You for the purchase of the applicable Subscription (“Order Form”).
(c) Basic Version License. Subject to the terms and conditions of this Agreement, the availability of such a License for the applicable Software and any applicable limitation on the number of Nodes, and in consideration of the Registration of Your use the Software, Elastic agrees to grant, and does hereby grant to You, for a period of one (1) year from the date of Registration, a License to use the Eligible Features and Functions of the Software that are applicable to the Basic Version of the Software. The foregoing license may be renewed annually upon the mutual agreement of the parties.
1.2 Reservation of Rights; Restrictions. As between Elastic and You, Elastic owns all right title and interest in and to the Software and any derivative works thereof, and except as expressly set forth in Section 1.1 above, no other license to the Software is granted to You by implication, estoppel or otherwise. You agree not to: (i) reverse engineer or decompile, decrypt, disassemble or otherwise reduce any Software or any portion thereof to human-readable form, except and only to the extent any such restriction is prohibited by applicable law, (ii) deploy the Software on more Nodes than are permitted under the applicable License grant in Section 1.1 above, (iii) where You have purchased a Subscription, use the Software in connection with any Project other than the Project for which You have purchased such Subscription, as identified on the applicable Order Form, (iv) prepare derivative works from, modify, copy or use the Software in any manner except as expressly permitted in this Agreement; (v) except as expressly permitted in Section 1.1 above, transfer, sell, rent, lease, distribute, sublicense, loan or otherwise transfer the Software in whole or in part to any third party; (vi) except as may be expressly permitted on an applicable Order Form or in another agreement between the parties, use the Software for providing time-sharing services, any software-as-a-service offering (“SaaS”), service bureau services or as part of an application services provider or other service offering; (vii) circumvent the limitations on use of the Software that are imposed or preserved by any License Key, (viii) alter or remove any Marks and Notices in the Software; (ix) deploy the Commercial Software on or in connection with any third party infrastructure as a service that includes any Elastic-branded software as a service; or (x) make available to any third party any analysis of the results of operation of the Software, including benchmarking results, without the prior written consent of Elastic. The Software may contain or be provided with open source libraries, components, utilities and other open source software (collectively, “Open Source Software”), which Open Source Software may have applicable license terms as identified on a website designated by Elastic or otherwise provided with the Software or Documentation. Notwithstanding anything to the contrary herein, use of the Open Source Software shall be subject to the license terms and conditions applicable to such Open Source Software, to the extent required by the applicable licensor (which terms shall not restrict the license rights granted to You hereunder, but may contain additional rights).
1.3 Audit Rights. You agree that, unless such right is waived in writing by Elastic, Elastic shall have the right, upon fifteen (15) days notice to You, to audit Your use of the Software for compliance with any limitations on Your use of the Software that are set forth herein. You agree to provide Elastic with the necessary access to the Software to conduct such an audit either (i) remotely, or (ii) if remote performance is not possible, at Your facilities, during normal business hours and no more than one (1) time in any twelve (12) month period. In the event any such audit reveals that You have used the Software in excess of the applicable quantitative limitations, You agree to promptly pay to Elastic an amount equal to the difference between the fees actually paid and the fees that You should have paid to remain in compliance with such quantitative limitations. This Section 1.3 shall survive for a period of two (2) years from the termination or expiration of this Agreement.
1.4 Cluster Metadata. You understand and agree that once deployed, and on a daily basis, the Software may provide metadata to Elastic about Your cluster statistics and associates that metadata with Your IP address. However, no other information is provided to Elastic by the Software, including any information about the data You process or store in connection with Your use of the Software. Instructions for disabling this feature are contained in the Software, however leaving this feature active enables Elastic to gather cluster statistics and provide an improved level of support to You.
2. TERM AND TERMINATION
2.1 Term. Unless earlier terminated under Section 2.2 below, this Agreement shall commence on the Effective Date, and shall continue in force for the term of the last to expire applicable license set forth in Section 1.1 above.
2.2 Termination. Either party may, upon written notice to the other party, terminate this Agreement for material breach by the other party automatically and without any other formality, if such party has failed to cure such material breach within thirty (30) days of receiving written notice of such material breach from the non-breaching party. Notwithstanding the foregoing, this Agreement shall automatically terminate in the event that You intentionally breach the scope of a license granted in Section 1.1 of this Agreement, provided that Elastic reserves the right to retroactively waive such automatic termination upon written notice to You.
2.3 Post Termination or Expiration. Upon termination or expiration of this Agreement, for any reason, You shall promptly cease the use of the Software and Documentation and destroy (and certify to Elastic in writing the fact of such destruction), or return to Elastic, all copies of the Software and Documentation then in Your possession or under Your control.
2.4 Survival. Sections 2.3, 2.4, 3, 4, 5 and 6 (as any such Sections may be modified by Attachment 1, if applicable) shall survive any termination or expiration of this Agreement.
3. LIMITED WARRANTY AND DISCLAIMER OF WARRANTIES
3.1 Limited Performance Warranty. Subject to You purchasing a Subscription, Elastic warrants that during the applicable Subscription Term, the Software will perform in all material respects in accordance with the Documentation. In the event of a breach of the foregoing warranty, Elastics sole obligation, and Your exclusive remedy shall be for Elastic to (i) correct any failure(s) of the Software to perform in all material respects in accordance with the Documentation or (ii) if Elastic is unable to provide such a correction within thirty (30) days of receipt of notice of the applicable non-conformity, You may elect to terminate this Agreement and the associated Subscription, and Elastic will promptly refund to You any pre-paid, unused fees paid by You to Elastic for the applicable Subscription. The warranty set forth in this Section 3.1 does not apply if the applicable Software or any portion thereof: (a) has been altered, except by or on behalf Elastic; (b) has not been used, installed, operated, repaired, or maintained in accordance with this Agreement and/or the Documentation; (c) has been subjected to abnormal physical or electrical stress, misuse, negligence, or accident; or (d) is used on equipment, products, or systems not meeting specifications identified by Elastic in the Documentation. Additionally, the warranties set forth herein only apply when notice of a warranty claim is provided to Elastic within the applicable warranty period specified herein and do not apply to any bug, defect or error caused by or attributable to software or hardware not supplied by Elastic.
3.2 Malicious Code. Elastic represents and warrants that prior to making it available for delivery to You, Elastic will use standard industry practices including, without limitation, the use of an updated commercial anti-virus program, to test the Software for Malicious Code and remove any Malicious Code it discovers. In the event of a breach of the foregoing warranty, Elastics sole obligation, and Your exclusive remedy shall be for Elastic to replace the Software with Software that does not contain any Malicious Code.
3.3 Warranty Disclaimer. EXCEPT AS EXPRESSLY SET FORTH IN THIS SECTION 3, TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, THE SOFTWARE IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, AND ELASTIC AND ITS LICENSORS MAKE NO WARRANTIES WHETHER EXPRESSED, IMPLIED OR STATUTORY REGARDING OR RELATING TO THE SOFTWARE OR DOCUMENTATION. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, ELASTIC AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT WITH RESPECT TO THE SOFTWARE AND DOCUMENTATION, AND WITH RESPECT TO THE USE OF THE FOREGOING. FURTHER, ELASTIC DOES NOT WARRANT RESULTS OF USE OR THAT THE SOFTWARE WILL BE ERROR FREE OR THAT THE USE OF THE SOFTWARE WILL BE UNINTERRUPTED.
4. LIMITATION OF LIABILITY
The provisions of this Section 4, including to the extent modified by an applicable provision in Attachment 1 hereto, apply if You have not purchased a Subscription. If you have purchased a Subscription, then the limitations of liability set forth in the applicable Subscription Agreement will apply in lieu of those set forth in this Section 4, including to the extent modified by an applicable provision in Attachment 1 hereto.
4.1 Disclaimer of Certain Damages. IN NO EVENT SHALL YOU OR ELASTIC OR ITS LICENSORS BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, BUSINESS INTERRUPTION, LOSS OF DATA, COST OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH OR ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE, OR THE PERFORMANCE OF OR FAILURE TO PERFORM THIS AGREEMENT, WHETHER ALLEGED AS A BREACH OF CONTRACT OR TORTIOUS CONDUCT, INCLUDING NEGLIGENCE, EVEN IF THE RESPONSIBLE PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE LIMITATIONS OF LIABILITY SET FORTH IN THIS SECTION 4.1 SHALL NOT APPLY TO A BREACH THROUGH GROSS NEGLIGENCE OR INTENTIONAL MISCONDUCT BY YOU OF THE SCOPE OF THE LICENSE GRANTED IN SECTION 1.1 OR TO ANY OTHER LIABILITY THAT CANNOT BE EXCLUDED OR LIMITED UNDER APPLICABLE LAW.
4.2 Damages Cap. IN NO EVENT SHALL ELASTICS OR ITS LICENSORS AGGREGATE, CUMULATIVE LIABILITY UNDER THIS AGREEMENT EXCEED ONE THOUSAND DOLLARS ($1,000).
4.3 YOU AGREE THAT THE FOREGOING LIMITATIONS, EXCLUSIONS AND DISCLAIMERS ARE A REASONABLE ALLOCATION OF THE RISK BETWEEN THE PARTIES AND WILL APPLY TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, EVEN IF ANY REMEDY FAILS IN ITS ESSENTIAL PURPOSE.
5. MISCELLANEOUS
This Agreement, including Attachment 1 hereto, which is hereby incorporated herein by this reference, as well as any applicable Order Form and Subscription Agreement, completely and exclusively state the entire agreement of the parties regarding the subject matter herein, and it supersedes, and its terms govern, all prior proposals, agreements, or other communications between the parties, oral or written, regarding such subject matter. In the event of any conflict between the terms and conditions of any of the foregoing documents, the conflict shall be resolved based on the following order of precedence: (i) an applicable Order Form (but only for the transaction thereunder), (ii) an applicable Subscription Agreement, (iii) the Support Services Policy and (iv) this Agreement. For the avoidance of doubt, the parties hereby expressly acknowledge and agree that if You issue any purchase order or similar document in connection with the purchase of a Subscription and/or obtaining of License to the Software, You will do so only for Your internal, administrative purposes and not with the intent to provide any contractual terms. This Agreement may not be modified except by a subsequently dated, written amendment that expressly amends this Agreement and which is signed on behalf of Elastic and You, by duly authorized representatives. If any provision hereof is held unenforceable, this Agreement will continue without said provision and be interpreted to reflect the original intent of the parties.
6. DEFINITIONS
The following terms have the meanings ascribed:
6.1 “Affiliate” means, with respect to a party, any entity that controls, is controlled by, or which is under common control with, such party, where “control” means ownership of at least fifty percent (50%) of the outstanding voting shares of the entity, or the contractual right to establish policy for, and manage the operations of, the entity.
6.2 “Basic Version” means that version of the Software available for use without the purchase of a Subscription, but which does require Registration.
6.3 “Contractor” means any third party contractor performing services on Your behalf.
6.4 “Documentation” means the published end user documentation provided by Elastic with the Software.
6.5 “Eligible Features and Functions” means those features and functions of the Software that are eligible for use with respect to the particular version of the Software licensed by You or the Subscription level purchased by You. A list of the Eligible Features and Functions that correspond to each version of the Software and Subscription levels may be found at https://www.elastic.co/subscriptions.
6.6 “License” means a limited, non-exclusive, non-transferable, fully paid up, right and license (without the right to grant or authorize sublicenses) solely for Your internal business operations to (i) install and use, in object code format, the Software, (ii) use, and distribute internally a reasonable number of copies of the Documentation, provided that You must include on such copies all Marks and Notices; (iii) permit Contractors and Your Affiliates to use the Software and Documentation as set forth in (i) and (ii) above, provided that such use by Contractors must be solely for Your benefit, and You shall be responsible for all acts and omissions of such Contractors and Affiliates in connection with their use of the Software that are contrary to the terms and conditions of this Agreement.
6.7 “License Key” means an alphanumeric code that enables the Eligible Features and Functions of the Software.
6.8 “Malicious Code” means any code that is designed to harm, or otherwise disrupt in any unauthorized manner, the operation of Your computer programs or computer systems or destroy or damage data. For clarity, Malicious Code shall not include any software bugs or errors handled through Support Services, or any standard features of functions of the Software and/or any License Key that are intended to enforce the temporal and/or other limitations on the scope of the use of the Software to the scope of the License granted to You.
6.9 “Marks and Notices” means all Elastic trademarks, trade names, logos and notices present on the Documentation as originally provided by Elastic.
6.10 “Node” means an instance of Software on a single physical server or virtual machine, provided that all client Nodes are excluded from calculating Subscription fees based on the number of Nodes.
6.11 “Project” means a specific use case for the Software, with Nodes being deployed for use in a logical grouping of functionality to support such use case.
6.12 “Registration” means Elastics then-current process under which You may register Your use of the Software with Elastic by providing certain information to Elastic regarding You and Your use of the Software.
6.13 “Subscription” means the right to receive Support Services and a License to the Software.
6.14 “Subscription Agreement” means a legally enforceable agreement between You and Elastic, under which You purchase a Subscription.
6.15 “Subscription Level” means the level of Subscription purchased by You. The Subscription Level purchased by You determines the specific Support Services that You are entitled to receive, and the specific Eligible Features and functions that You are entitled to use.
6.16 “Subscription Term” means the period of time for which You have purchased a Subscription.
6.17 “Trial Version” means that version of the Software available for use without the purchase of a Subscription and without Registration.
ATTACHMENT 1
ADDITIONAL TERMS AND CONDITIONS
A. The following additional terms and conditions apply to all Customers with principal offices in the United States of America:
(1) Applicable Elasticsearch Entity. The entity providing the license is Elasticsearch, Inc., a Delaware corporation.
(2) Government Rights. The Software product is "Commercial Computer Software," as that term is defined in 48 C.F.R. 2.101, and as the term is used in 48 C.F.R. Part 12, and is a Commercial Item comprised of "commercial computer software" and "commercial computer software documentation". If acquired by or on behalf of a civilian agency, the U.S. Government acquires this commercial computer software and/or commercial computer software documentation subject to the terms of this Agreement, as specified in 48 C.F.R. 12.212 (Computer Software) and 12.211 (Technical Data) of the Federal Acquisition Regulation ("FAR") and its successors. If acquired by or on behalf of any agency within the Department of Defense ("DOD"), the U.S. Government acquires this commercial computer software and/or commercial computer software documentation subject to the terms of the Elastic Software End User License Agreement as specified in 48 C.F.R. 227.7202-3 and 48 C.F.R. 227.7202-4 of the DOD FAR Supplement ("DFARS") and its successors, and consistent with 48 C.F.R. 227.7202. This U.S. Government Rights clause, consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202 is in lieu of, and supersedes, any other FAR, DFARS, or other clause or provision that addresses Government rights in computer software, computer software documentation or technical data related to the Software under this Agreement and in any Subcontract under which this commercial computer software and commercial computer software documentation is acquired or licensed.
(3) Export Control. You acknowledge that the goods, software and technology acquired from Elastic are subject to U.S. export control laws and regulations, including but not limited to the International Traffic In Arms Regulations (“ITAR”) (22 C.F.R. Parts 120-130 (2010)); the Export Administration Regulations ("EAR") (15 C.F.R. Parts 730-774 (2010)); the U.S. antiboycott regulations in the EAR and U.S. Department of the Treasury regulations; the economic sanctions regulations and guidelines of the U.S. Department of the Treasury, Office of Foreign Assets Control, and the USA Patriot Act (Title III of Pub. L. 107-56, signed into law October 26, 2001), as amended.  You are now and will remain in the future compliant with all such export control laws and regulations, and will not export, re-export, otherwise transfer any Elastic goods, software or technology or disclose any Elastic software or technology to any person contrary to such laws or regulations.  You acknowledge that remote access to the Software may in certain circumstances be considered a re-export of Software, and accordingly, may not be granted in contravention of U.S. export control laws and regulations.
(4) Governing Law, Jurisdiction and Venue.
(a) Customers in California. If Customer is located in California (as determined by the Customer address on the applicable Order Form, or for a trial license under 1.1(a), the location of person who installed the Software), this Agreement will be governed by the laws of the State of California, without regard to its conflict of laws principles, and all suits hereunder will be brought solely in Federal Court for the Northern District of California, or if that court lacks subject matter jurisdiction, in any California State Court located in Santa Clara County.
(b) Customers Outside of California. If Customer is located anywhere other than California (as determined by the Customer address on the applicable Order Form, or for a trial license under 1.1(a), the location of person who installed the Software), this Agreement will be governed by the laws of the State of Delaware, without regard to its conflict of laws principles, and all suits hereunder will be brought solely in Federal Court for the District of Delaware, or if that court lacks subject matter jurisdiction, in any Delaware State Court located in Wilmington, Delaware.
(c) All Customers. This Agreement shall not be governed by the 1980 UN Convention on Contracts for the International Sale of Goods. The parties hereby irrevocably waive any and all claims and defenses either might otherwise have in any action or proceeding in any of the applicable courts set forth in (a) or (b) above, based upon any alleged lack of personal jurisdiction, improper venue, forum non conveniens, or any similar claim or defense.
(d) Equitable Relief. A breach or threatened breach, by either party of Section 4 may cause irreparable harm for which the non-breaching party shall be entitled to seek injunctive relief without being required to post a bond.
B. The following additional terms and conditions apply to all Customers with principal offices in Canada:
(1) Applicable Elasticsearch Entity. The entity providing the license is Elasticsearch B.C. Ltd., a corporation incorporated under laws of the Province of British Columbia.
(2) Export Control. You acknowledge that the goods, software and technology acquired from Elastic are subject to the restrictions and controls set out in Section A(3) above as well as those imposed by the Export and Import Permits Act (Canada) and the regulations thereunder and that you will comply with all applicable laws and regulations. Without limitation, You acknowledge that the Software, or any portion thereof, will not be exported: (a) to any country on Canada's Area Control List; (b) to any country subject to UN Security Council embargo or action; or (c) contrary to Canada's Export Control List Item 5505. You are now and will remain in the future compliant with all such export control laws and regulations, and will not export, re-export, otherwise transfer any Elastic goods, software or technology or disclose any Elastic software or technology to any person contrary to such laws or regulations.  You will not export or re-export the Software, or any portion thereof, directly or indirectly, in violation of the Canadian export administration laws and regulations to any country or end user, or to any end user who you know or have reason to know will utilize them in the design, development or production of nuclear, chemical or biological weapons. You further acknowledge that the Software product may include technical data subject to such Canadian export regulations. Elastic does not represent that the Software is appropriate or available for use in all countries. Elastic prohibits accessing materials from countries or states where contents are illegal. You are using the Software on your own initiative and you are responsible for compliance with all applicable laws. You hereby agree to indemnify Elastic and its Affiliates from any claims, actions, liability or expenses (including reasonable lawyers' fees) resulting from Your failure to act in accordance with the acknowledgements, agreements, and representations in this Section B(2).
(3) Governing Law and Dispute Resolution. This Agreement shall be governed by the Province of Ontario and the federal laws of Canada applicable therein without regard to conflict of laws provisions. The parties hereby irrevocably waive any and all claims and defenses either might otherwise have in any such action or proceeding in any of such courts based upon any alleged lack of personal jurisdiction, improper venue, forum non conveniens or any similar claim or defense. Any dispute, claim or controversy arising out of or relating to this Agreement or the existence, breach, termination, enforcement, interpretation or validity thereof, including the determination of the scope or applicability of this agreement to arbitrate, (each, a “Dispute”), which the parties are unable to resolve after good faith negotiations, shall be submitted first to the upper management level of the parties. The parties, through their upper management level representatives shall meet within thirty (30) days of the Dispute being referred to them and if the parties are unable to resolve such Dispute within thirty (30) days of meeting, the parties agree to seek to resolve the Dispute through mediation with ADR Chambers in the City of Toronto, Ontario, Canada before pursuing any other proceedings. The costs of the mediator shall be shared equally by the parties. If the Dispute has not been resolved within thirty (30) days of the notice to desire to mediate, any party may terminate the mediation and proceed to arbitration and the matter shall be referred to and finally resolved by arbitration at ADR Chambers pursuant to the general ADR Chambers Rules for Arbitration in the City of Toronto, Ontario, Canada. The arbitration shall proceed in accordance with the provisions of the Arbitration Act (Ontario). The arbitral panel shall consist of three (3) arbitrators, selected as follows: each party shall appoint one (1) arbitrator; and those two (2) arbitrators shall discuss and select a chairman. If the two (2) party-appointed arbitrators are unable to agree on the chairman, the chairman shall be selected in accordance with the applicable rules of the arbitration body. Each arbitrator shall be independent of each of the parties. The arbitrators shall have the authority to grant specific performance and to allocate between the parties the costs of arbitration (including service fees, arbitrator fees and all other fees related to the arbitration) in such equitable manner as the arbitrators may determine. The prevailing party in any arbitration shall be entitled to receive reimbursement of its reasonable expenses incurred in connection therewith. Judgment upon the award so rendered may be entered in a court having jurisdiction or application may be made to such court for judicial acceptance of any award and an order of enforcement, as the case may be. Notwithstanding the foregoing, Elastic shall have the right to institute an action in a court of proper jurisdiction for preliminary injunctive relief pending a final decision by the arbitrator, provided that a permanent injunction and damages shall only be awarded by the arbitrator. The language to be used in the arbitral proceedings shall be English.
(4) Language. Any translation of this Agreement is done for local requirements and in the event of a dispute between the English and any non-English version, the English version of this Agreement shall govern. At the request of the parties, the official language of this Agreement and all communications and documents relating hereto is the English language, and the English-language version shall govern all interpretation of the Agreement.  À la demande des parties, la langue officielle de la présente convention ainsi que toutes communications et tous documents s'y rapportant est la langue anglaise, et la version anglaise est celle qui régit toute interprétation de la présente convention.
(5) Warranty Disclaimer. For Customers with principal offices in the Province of Québec, the following new sentence is to be added to the end of Section 3.3: “SOME JURISDICTIONS DO NOT ALLOW LIMITATIONS OR EXCLUSIONS OF CERTAIN TYPES OF DAMAGES AND/OR WARRANTIES AND CONDITIONS. THE LIMITATIONS, EXCLUSIONS AND DISCLAIMERS SET FORTH IN THIS AGREEMENT SHALL NOT APPLY IF AND ONLY IF AND TO THE EXTENT THAT THE LAWS OF A COMPETENT JURISDICTION REQUIRE LIABILITIES BEYOND AND DESPITE THESE LIMITATIONS, EXCLUSIONS AND DISCLAIMERS.”
(6) Limitation of Liability. For Customers with principal offices in the Province of Québec, the following new sentence is to be added to the end of Section 4.1: “SOME JURISDICTIONS DO NOT ALLOW LIMITATIONS OR EXCLUSIONS OF CERTAIN TYPES OF DAMAGES AND/OR WARRANTIES AND CONDITIONS.  THE LIMITATIONS, EXCLUSIONS AND DISCLAIMERS SET FORTH IN THIS AGREEMENT SHALL NOT APPLY IF AND ONLY IF AND TO THE EXTENT THAT THE LAWS OF A COMPETENT JURISDICTION REQUIRE LIABILITIES BEYOND AND DESPITE THESE LIMITATIONS, EXCLUSIONS AND DISCLAIMERS.”
C. The following additional terms and conditions apply to all Customers with principal offices outside of the United States of America and Canada:
(1) Applicable Elasticsearch Entity. The entity providing the license in Germany is Elasticsearch Gmbh; in France is Elasticsearch SARL, in the United Kingdom is Elasticsearch Ltd, in Australia is Elasticsearch Pty Ltd., in Japan is Elasticsearch KK, in Sweden is Elasticsearch AB, in Norway is Elasticsearch AS and in all other countries is Elasticsearch BV.
(2) Choice of Law. This Agreement shall be governed by and construed in accordance with the laws of the State of New York, without reference to or application of choice of law rules or principles. Notwithstanding any choice of law provision or otherwise, the Uniform Computer Information Transactions Act (UCITA) and the United Nations Convention on the International Sale of Goods shall not apply.
(3) Arbitration. Any dispute, claim or controversy arising out of or relating to this Agreement or the existence, breach, termination, enforcement, interpretation or validity thereof, including the determination of the scope or applicability of this agreement to arbitrate, (each, a “Dispute”) shall be referred to and finally resolved by arbitration under the rules and at the location identified below. The arbitral panel shall consist of three (3) arbitrators, selected as follows: each party shall appoint one (1) arbitrator; and those two (2) arbitrators shall discuss and select a chairman. If the two party-appointed arbitrators are unable to agree on the chairman, the chairman shall be selected in accordance with the applicable rules of the arbitration body. Each arbitrator shall be independent of each of the parties. The arbitrators shall have the authority to grant specific performance and to allocate between the parties the costs of arbitration (including service fees, arbitrator fees and all other fees related to the arbitration) in such equitable manner as the arbitrators may determine. The prevailing party in any arbitration shall be entitled to receive reimbursement of its reasonable expenses incurred in connection therewith. Judgment upon the award so rendered may be entered in a court having jurisdiction or application may be made to such court for judicial acceptance of any award and an order of enforcement, as the case may be. Notwithstanding the foregoing, Elastic shall have the right to institute an action in a court of proper jurisdiction for preliminary injunctive relief pending a final decision by the arbitrator, provided that a permanent injunction and damages shall only be awarded by the arbitrator. The language to be used in the arbitral proceedings shall be English.
In addition, the following terms only apply to Customers with principal offices within Europe, the Middle East or Africa (EMEA):
Arbitration Rules and Location. Any Dispute shall be referred to and finally resolved by arbitration under the London Court of International Arbitration (“LCIA”) Rules (which Rules are deemed to be incorporated by reference into this clause) on the basis that the governing law is the law of the State of New York, USA. The seat, or legal place, of arbitration shall be London, England.
(b) In addition, the following terms only apply to Customers with principal offices within Asia Pacific, Australia & New Zealand:
Arbitration Rules and Location. Any Dispute shall be referred to and finally resolved by arbitration under the Rules of Conciliation and Arbitration of the International Chamber of Commerce (“ICC”) in force on the date when the notice of arbitration is submitted in accordance with such Rules (which Rules are deemed to be incorporated by reference into this clause) on the basis that the governing law is the law of the State of New York, USA. The seat, or legal place, of arbitration shall be Singapore.
(c) In addition, the following terms only apply to Customers with principal offices within the Americas (excluding North America):
Arbitration Rules and Location. Any Dispute shall be referred to and finally resolved by arbitration under International Dispute Resolution Procedures of the American Arbitration Association (“AAA”) in force on the date when the notice of arbitration is submitted in accordance with such Procedures (which Procedures are deemed to be incorporated by reference into this clause) on the basis that the governing law is the law of the State of New York, USA. The seat, or legal place, of arbitration shall be New York, New York, USA.
(4) In addition, for Customers with principal offices within the UK, the following new sentence is added to the end of Section 4.1:
Nothing in this Agreement shall have effect so as to limit or exclude a partys liability for death or personal injury caused by negligence or for fraud including fraudulent misrepresentation and this Section 4.1 shall take effect subject to this provision.
(5) In addition, for Customers with principal offices within France, Sections 1.2, 3 and 4.1 of the Agreement are deleted and replaced with the following new Sections 1.2, 3.3 and 4.1:
1.2 Reservation of Rights; Restrictions. Elastic owns all right title and interest in and to the Software and any derivative works thereof, and except as expressly set forth in Section 1.1 above, no other license to the Software is granted to You by implication, or otherwise. You agree not to prepare derivative works from, modify, copy or use the Software in any manner except as expressly permitted in this Agreement; provided that You may copy the Software for archival purposes, only where such software is provided on a non-durable medium; and You may decompile the Software, where necessary for interoperability purposes and where necessary for the correction of errors making the software unfit for its intended purpose, if such right is not reserved by Elastic as editor of the Software. Pursuant to article L122-6-1 of the French intellectual property code, Elastic reserves the right to correct any bugs as necessary for the Software to serve its intended purpose. You agree not to: (i) transfer, sell, rent, lease, distribute, sublicense, loan or otherwise transfer the Software in whole or in part to any third party; (ii) use the Software for providing time-sharing services, any software-as-a-service offering (“SaaS”), service bureau services or as part of an application services provider or other service offering; (iii) alter or remove any proprietary notices in the Software; or (iv) make available to any third party any analysis of the results of operation of the Software, including benchmarking results, without the prior written consent of Elastic.
3.3 Warranty Disclaimer. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, THE SOFTWARE IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, AND ELASTIC AND ITS LICENSORS MAKE NO WARRANTIES WHETHER EXPRESSED, IMPLIED OR STATUTORY REGARDING OR RELATING TO THE SOFTWARE OR DOCUMENTATION. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, ELASTIC AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE WITH RESPECT TO THE SOFTWARE AND DOCUMENTATION, AND WITH RESPECT TO THE USE OF THE FOREGOING. FURTHER, ELASTIC DOES NOT WARRANT RESULTS OF USE OR THAT THE SOFTWARE WILL BE ERROR FREE OR THAT THE USE OF THE SOFTWARE WILL BE UNINTERRUPTED.
4.1 Disclaimer of Certain Damages. IN NO EVENT SHALL YOU OR ELASTIC OR ITS LICENSORS BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, BUSINESS INTERRUPTION, LOSS OF DATA, COST OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT OR UNFORESEEABLE DAMAGES OF ANY KIND IN CONNECTION WITH OR ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE, OR THE PERFORMANCE OF OR FAILURE TO PERFORM THIS AGREEMENT, WHETHER ALLEGED AS A BREACH OF CONTRACT OR TORTIOUS CONDUCT, INCLUDING NEGLIGENCE. THE LIMITATIONS OF LIABILITY SET FORTH IN THIS SECTION 4.1 SHALL NOT APPLY TO A BREACH, THROUGH GROSS NEGLIGENCE OR INTENTIONAL MISCONDUCT BY YOU, OF THE SCOPE OF THE LICENSE GRANTED IN SECTION 1.1, OR IN CASE OF DEATH OR PERSONAL INJURY.
(6) In addition, for Customers located within Australia: (a) Sections 3.1, 3.2 and 3.3 of the Agreement are deleted and replaced with the following new Sections 3.1, 3.2, 3.3, 3.4 and 3.5; and (b) Sections 4.1, 4.2 and 4.3 of the Agreement are deleted and replaced with the following new Sections 4.1, 4.2, and 4.3:
3.1 Despite anything in this Agreement, Elastics goods come with guarantees that cannot be excluded under the Australian Consumer Law (as set out in the Competition and Consumer Act 2010 (Cth)). You are entitled to a replacement or refund for a major failure and compensation for any other reasonably foreseeable loss or damage. You are also entitled to have the goods repaired or replaced if the goods fail to be of acceptable quality and the failure does not amount to a major failure.
3.2 Limited Performance Warranty. Subject to You purchasing a Subscription, Elastic warrants that during the applicable Subscription Term, the Software will perform in all material respects in accordance with the Documentation. In the event of a breach of the foregoing warranty during the Subscription Term and where You notify Elastic that the Software does not perform in all material respects in accordance with the Documentation, Elastics sole obligation, and Your exclusive remedy shall be for Elastic to (i) correct (at Elastics cost) any failure(s) of the Software to perform in all material respects in accordance with the Documentation or (ii) if Elastic is unable to provide such a correction within thirty (30) days of receipt of notice of the applicable non-conformity, You may elect to terminate this Agreement and the associated Subscription, and Elastic will promptly refund to You any pre-paid, unused fees paid by You to Elastic for the applicable Subscription. The warranty set forth in this Section 3.2 does not apply if the applicable Software or any portion thereof: (a) has been altered, except by or on behalf Elastic; (b) has not been used, installed, operated, repaired, or maintained in accordance with this Agreement and/or the Documentation; (c) has been subjected to abnormal physical or electrical stress, misuse, negligence, or accident; or (d) is used on equipment, products, or systems not meeting specifications identified by Elastic in the Documentation. Additionally, the warranties set forth herein only apply when notice of a warranty claim is provided to Elastic within the applicable warranty period specified herein and do not apply to any bug, defect or error caused by or attributable to software or hardware not supplied by Elastic.
3.3 For the purposes of Section 3.2, You must use the contact details set out below to notify Elastic that the Software does not perform in all material respects in accordance with the Documentation:
Elasticsearch Pty Ltd
4th Floor, 17-19 Alberta Street
Sydney, New South Wales, 2000, Australia
3.4 Malicious Code. Elastic represents and warrants that prior to making it available for delivery to You, Elastic will use standard industry practices including, without limitation, the use of an updated commercial anti-virus program, to test the Software for Malicious Code and remove any Malicious Code it discovers. In the event of a breach of the foregoing warranty, Elastics sole obligation, and Your exclusive remedy shall be, at Elastics option, for Elastic to replace the Software with Software that does not contain any Malicious Code or to pay for the cost of the Software to be replaced with Software that does not contain any Malicious Code.
3.5 Warranty Disclaimer. NOTHING IN THIS AGREEMENT IS INTENDED TO LIMIT CUSTOMERS NON-EXCLUDABLE RIGHTS UNDER THE COMPETITION AND CONSUMER ACT 2010 (CTH). EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT AND TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, THE SOFTWARE IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, AND ELASTIC AND ITS LICENSORS MAKE NO WARRANTIES WHETHER EXPRESSED, IMPLIED OR STATUTORY REGARDING OR RELATING TO THE SOFTWARE OR DOCUMENTATION. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW AND EXCEPT AS SET OUT IN THIS AGREEMENT, ELASTIC AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT WITH RESPECT TO THE SOFTWARE AND DOCUMENTATION, AND WITH RESPECT TO THE USE OF THE FOREGOING. FURTHER, ELASTIC DOES NOT WARRANT RESULTS OF USE OR THAT THE SOFTWARE WILL BE ERROR FREE OR THAT THE USE OF THE SOFTWARE WILL BE UNINTERRUPTED.
4.1 Disclaimer of Certain Damages. Subject to clause 4.3, a party is not liable for Consequential Loss however caused (including by the negligence of that party) suffered or incurred by the other party in connection with this agreement. “Consequential Loss” means loss of revenues, loss of reputation, indirect loss, loss of profits, consequential loss, loss of actual or anticipated savings, indirect loss, lost opportunities, including opportunities to enter into arrangements with third parties, loss or damage in connection with claims against by third parties, or loss or corruption or data.
4.2 Damages Cap. SUBJECT TO CLAUSES 4.1 AND 4.3, ANY LIABILITY OF ELASTIC FOR ANY LOSS OR DAMAGE, HOWEVER CAUSED (INCLUDING BY THE NEGLIGENCE OF ELASTIC), SUFFERED BY YOU IN CONNECTION WITH THIS AGREEMENT IS LIMITED TO ONE THOUSAND DOLLARS ($1,000). THE LIMITATION SET OUT IN THIS SECTION 4.2 IS AN AGGREGATE LIMIT FOR ALL CLAIMS, WHENEVER MADE.
4.3 Australian Consumer Law. IF THE COMPETITION AND CONSUMER ACT 2010 (CTH) OR ANY OTHER LEGISLATION STATES THAT THERE IS A GUARANTEE IN RELATION TO ANY GOOD OR SERVICE SUPPLIED BY ELASTIC IN CONNECTION WITH THIS AGREEMENT, AND ELASTICS LIABILITY FOR FAILING TO COMPLY WITH THAT GUARANTEE CANNOT BE EXCLUDED BUT MAY BE LIMITED, SECTIONS 4.1, 4.2 AND 4.3 DO NOT APPLY TO THAT LIABILITY. INSTEAD, ELASTICS LIABILITY FOR THAT FAILURE IS LIMITED TO (AT THE ELECTION OF ELASTIC), IN THE CASE OF A SUPPLY OF GOODS, ELASTIC REPLACING THE GOODS OR SUPPLYING EQUIVALENT GOODS OR REPAIRING THE GOODS, OR IN THE CASE OF A SUPPLY OF SERVICES, ELASTIC SUPPLYING THE SERVICES AGAIN OR PAYING THE COST OF HAVING THE SERVICES SUPPLIED AGAIN.
(7) In addition, for Customers with principal offices within Japan, Sections 1.2, 3 and 4.1 of the Agreement are deleted and replaced with the following new Sections 1.2, 3.3 and 4.1:
1.2 Reservation of Rights; Restrictions. As between Elastic and You, Elastic owns all right title and interest in and to the Software and any derivative works thereof, and except as expressly set forth in Section 1.1 above, no other license to the Software is granted to You by implication or otherwise. You agree not to: (i) prepare derivative works from, modify, copy or use the Software in any manner except as expressly permitted in this Agreement or applicable law; (ii) transfer, sell, rent, lease, distribute, sublicense, loan or otherwise transfer the Software in whole or in part to any third party; (iii) use the Software for providing time-sharing services, any software-as-a-service offering (“SaaS”), service bureau services or as part of an application services provider or other service offering; (iv) alter or remove any proprietary notices in the Software; or (v) make available to any third party any analysis of the results of operation of the Software, including benchmarking results, without the prior written consent of Elastic.
3.3 Warranty Disclaimer. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, THE SOFTWARE IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, AND ELASTIC AND ITS LICENSORS MAKE NO WARRANTIES WHETHER EXPRESSED, IMPLIED OR STATUTORY REGARDING OR RELATING TO THE SOFTWARE OR DOCUMENTATION. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, ELASTIC AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT WITH RESPECT TO THE SOFTWARE AND DOCUMENTATION, AND WITH RESPECT TO THE USE OF THE FOREGOING. FURTHER, ELASTIC DOES NOT WARRANT RESULTS OF USE OR THAT THE SOFTWARE WILL BE ERROR FREE OR THAT THE USE OF THE SOFTWARE WILL BE UNINTERRUPTED.
4.1 Disclaimer of Certain Damages. IN NO EVENT SHALL YOU OR ELASTIC OR ITS LICENSORS BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, BUSINESS INTERRUPTION, LOSS OF DATA, COST OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY SPECIALINDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH OR ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE, OR THE PERFORMANCE OF OR FAILURE TO PERFORM THIS AGREEMENT, WHETHER ALLEGED AS A BREACH OF CONTRACT OR TORTIOUS CONDUCT, INCLUDING NEGLIGENCE, EVEN IF THE RESPONSIBLE PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE LIMITATIONS OF LIABILITY SET FORTH IN THIS SECTION 4.1 SHALL NOT APPLY TO A BREACH THROUGH GROSS NEGLIGENCE OR INTENTIONAL MISCONDUCT BY YOU OF THE SCOPE OF THE LICENSE GRANTED IN SECTION 1.1 OR TO ANY OTHER LIABILITY THAT CANNOT BE EXCLUDED OR LIMITED UNDER APPLICABLE LAW.

View File

@ -1,5 +0,0 @@
Elasticsearch
Copyright 2009-2017 Elasticsearch
This product includes software developed by The Apache Software
Foundation (http://www.apache.org/).

View File

@ -516,7 +516,7 @@ public class MachineLearning implements ActionPlugin {
// 4 threads per job: for cpp logging, result processing, state processing and
// AutodetectProcessManager worker thread:
FixedExecutorBuilder autoDetect = new FixedExecutorBuilder(settings, AUTODETECT_THREAD_POOL_NAME,
maxNumberOfJobs * 4, 4, "xpack.ml.autodetect_thread_pool");
maxNumberOfJobs * 4, maxNumberOfJobs * 4, "xpack.ml.autodetect_thread_pool");
// 4 threads per job: processing logging, result and state of the renormalization process.
// Renormalization does't run for the entire lifetime of a job, so additionally autodetect process

View File

@ -34,8 +34,6 @@ import org.elasticsearch.xpack.ml.job.results.Forecast;
import java.io.IOException;
import java.util.Objects;
import static org.elasticsearch.xpack.ml.action.ForecastJobAction.Request.END_TIME;
public class ForecastJobAction extends Action<ForecastJobAction.Request, ForecastJobAction.Response, ForecastJobAction.RequestBuilder> {
public static final ForecastJobAction INSTANCE = new ForecastJobAction();
@ -57,15 +55,16 @@ public class ForecastJobAction extends Action<ForecastJobAction.Request, Forecas
public static class Request extends TransportJobTaskAction.JobTaskRequest<Request> implements ToXContentObject {
public static final ParseField END_TIME = new ParseField("end");
public static final ParseField DURATION = new ParseField("duration");
public static final ParseField EXPIRES_IN = new ParseField("expires_in");
// Max allowed duration: 8 weeks
private static final TimeValue MAX_DURATION = TimeValue.parseTimeValue("56d", "");
private static final ObjectParser<Request, Void> PARSER = new ObjectParser<>(NAME, Request::new);
static {
PARSER.declareString((request, jobId) -> request.jobId = jobId, Job.ID);
PARSER.declareString(Request::setEndTime, END_TIME);
PARSER.declareString(Request::setDuration, DURATION);
PARSER.declareString(Request::setExpiresIn, EXPIRES_IN);
}
@ -78,7 +77,6 @@ public class ForecastJobAction extends Action<ForecastJobAction.Request, Forecas
return request;
}
private String endTime;
private TimeValue duration;
private TimeValue expiresIn;
@ -89,20 +87,24 @@ public class ForecastJobAction extends Action<ForecastJobAction.Request, Forecas
super(jobId);
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public TimeValue getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = TimeValue.parseTimeValue(duration, DURATION.getPreferredName());
setDuration(TimeValue.parseTimeValue(duration, DURATION.getPreferredName()));
}
public void setDuration(TimeValue duration) {
this.duration = duration;
if (this.duration.compareTo(TimeValue.ZERO) <= 0) {
throw new IllegalArgumentException("[" + DURATION.getPreferredName() + "] must be positive: ["
+ duration.getStringRep() + "]");
}
if (this.duration.compareTo(MAX_DURATION) > 0) {
throw new IllegalArgumentException("[" + DURATION.getPreferredName() + "] must be " + MAX_DURATION.getStringRep()
+ " or less: [" + duration.getStringRep() + "]");
}
}
public TimeValue getExpiresIn() {
@ -110,13 +112,20 @@ public class ForecastJobAction extends Action<ForecastJobAction.Request, Forecas
}
public void setExpiresIn(String expiration) {
this.expiresIn = TimeValue.parseTimeValue(expiration, EXPIRES_IN.getPreferredName());
setExpiresIn(TimeValue.parseTimeValue(expiration, EXPIRES_IN.getPreferredName()));
}
public void setExpiresIn(TimeValue expiresIn) {
this.expiresIn = expiresIn;
if (this.expiresIn.compareTo(TimeValue.ZERO) < 0) {
throw new IllegalArgumentException("[" + EXPIRES_IN.getPreferredName() + "] must be non-negative: ["
+ expiresIn.getStringRep() + "]");
}
}
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
this.endTime = in.readOptionalString();
this.duration = in.readOptionalWriteable(TimeValue::new);
this.expiresIn = in.readOptionalWriteable(TimeValue::new);
}
@ -124,14 +133,13 @@ public class ForecastJobAction extends Action<ForecastJobAction.Request, Forecas
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeOptionalString(endTime);
out.writeOptionalWriteable(duration);
out.writeOptionalWriteable(expiresIn);
}
@Override
public int hashCode() {
return Objects.hash(jobId, endTime, duration, expiresIn);
return Objects.hash(jobId, duration, expiresIn);
}
@Override
@ -143,17 +151,15 @@ public class ForecastJobAction extends Action<ForecastJobAction.Request, Forecas
return false;
}
Request other = (Request) obj;
return Objects.equals(jobId, other.jobId) && Objects.equals(endTime, other.endTime) &&
Objects.equals(duration, other.duration) && Objects.equals(expiresIn, other.expiresIn);
return Objects.equals(jobId, other.jobId)
&& Objects.equals(duration, other.duration)
&& Objects.equals(expiresIn, other.expiresIn);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field(Job.ID.getPreferredName(), jobId);
if (endTime != null) {
builder.field(END_TIME.getPreferredName(), endTime);
}
if (duration != null) {
builder.field(DURATION.getPreferredName(), duration.getStringRep());
}
@ -258,9 +264,6 @@ public class ForecastJobAction extends Action<ForecastJobAction.Request, Forecas
@Override
protected void taskOperation(Request request, OpenJobAction.JobTask task, ActionListener<Response> listener) {
ForecastParams.Builder paramsBuilder = ForecastParams.builder();
if (request.getEndTime() != null) {
paramsBuilder.endTime(request.getEndTime(), END_TIME);
}
if (request.getDuration() != null) {
paramsBuilder.duration(request.getDuration());
}

View File

@ -214,7 +214,9 @@ class ScrollDataExtractor implements DataExtractor {
}
private void resetScroll() {
clearScroll(scrollId);
if (scrollId != null) {
clearScroll(scrollId);
}
scrollId = null;
}

View File

@ -164,7 +164,6 @@ public final class Messages {
"Model snapshot ''{0}'' is the active snapshot for job ''{1}'', so cannot be deleted";
public static final String REST_INVALID_DATETIME_PARAMS =
"Query param [{0}] with value [{1}] cannot be parsed as a date or converted to a number (epoch).";
public static final String REST_INVALID_DURATION_AND_ENDTIME = "Specify either duration or end time";
public static final String REST_INVALID_FLUSH_PARAMS_MISSING = "Invalid flush parameters: ''{0}'' has not been specified.";
public static final String REST_INVALID_FLUSH_PARAMS_UNEXPECTED = "Invalid flush parameters: unexpected ''{0}''.";
public static final String REST_JOB_NOT_CLOSED_REVERT = "Can only revert to a model snapshot when the job is closed.";

View File

@ -95,6 +95,7 @@ import java.util.function.Consumer;
import java.util.function.Supplier;
import static org.elasticsearch.xpack.ClientHelper.ML_ORIGIN;
import static org.elasticsearch.xpack.ClientHelper.clientWithOrigin;
import static org.elasticsearch.xpack.ClientHelper.executeAsyncWithOrigin;
import static org.elasticsearch.xpack.ClientHelper.stashWithOrigin;
@ -515,7 +516,7 @@ public class JobProvider {
* @return a bucket {@link BatchedResultsIterator}
*/
public BatchedResultsIterator<Bucket> newBatchedBucketsIterator(String jobId) {
return new BatchedBucketsIterator(client, jobId);
return new BatchedBucketsIterator(clientWithOrigin(client, ML_ORIGIN), jobId);
}
/**
@ -527,7 +528,7 @@ public class JobProvider {
* @return a record {@link BatchedResultsIterator}
*/
public BatchedResultsIterator<AnomalyRecord> newBatchedRecordsIterator(String jobId) {
return new BatchedRecordsIterator(client, jobId);
return new BatchedRecordsIterator(clientWithOrigin(client, ML_ORIGIN), jobId);
}
/**
@ -702,7 +703,7 @@ public class JobProvider {
* @return an influencer {@link BatchedResultsIterator}
*/
public BatchedResultsIterator<Influencer> newBatchedInfluencersIterator(String jobId) {
return new BatchedInfluencersIterator(client, jobId);
return new BatchedInfluencersIterator(clientWithOrigin(client, ML_ORIGIN), jobId);
}
/**

View File

@ -383,7 +383,7 @@ public class AutodetectProcessManager extends AbstractComponent {
client, jobId, renormalizer, jobResultsPersister, jobProvider, autodetectParams.modelSizeStats(),
autodetectParams.modelSnapshot() != null);
ExecutorService autodetectWorkerExecutor;
try {
try (ThreadContext.StoredContext ignore = threadPool.getThreadContext().stashContext()) {
autodetectWorkerExecutor = createAutodetectExecutorService(autoDetectExecutorService);
autoDetectExecutorService.submit(() -> processor.process(process));
} catch (EsRejectedExecutionException e) {

View File

@ -5,13 +5,8 @@
*/
package org.elasticsearch.xpack.ml.job.process.autodetect.params;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.mapper.DateFieldMapper;
import org.elasticsearch.xpack.ml.job.messages.Messages;
import java.util.Objects;
@ -19,14 +14,12 @@ public class ForecastParams {
private final String forecastId;
private final long createTime;
private final long endTime;
private final long duration;
private final long expiresIn;
private ForecastParams(String forecastId, long createTime, long endTime, long duration, long expiresIn) {
private ForecastParams(String forecastId, long createTime, long duration, long expiresIn) {
this.forecastId = forecastId;
this.createTime = createTime;
this.endTime = endTime;
this.duration = duration;
this.expiresIn = expiresIn;
}
@ -43,14 +36,6 @@ public class ForecastParams {
return createTime;
}
/**
* The forecast end time in seconds from the epoch
* @return The end time in seconds from the epoch
*/
public long getEndTime() {
return endTime;
}
/**
* The forecast duration in seconds
* @return The duration in seconds
@ -69,7 +54,7 @@ public class ForecastParams {
@Override
public int hashCode() {
return Objects.hash(forecastId, createTime, endTime, duration, expiresIn);
return Objects.hash(forecastId, createTime, duration, expiresIn);
}
@Override
@ -83,7 +68,6 @@ public class ForecastParams {
ForecastParams other = (ForecastParams) obj;
return Objects.equals(forecastId, other.forecastId)
&& Objects.equals(createTime, other.createTime)
&& Objects.equals(endTime, other.endTime)
&& Objects.equals(duration, other.duration)
&& Objects.equals(expiresIn, other.expiresIn);
}
@ -95,33 +79,18 @@ public class ForecastParams {
public static class Builder {
private final String forecastId;
private final long createTimeEpochSecs;
private long endTimeEpochSecs;
private long durationSecs;
private long expiresInSecs;
private Builder() {
forecastId = UUIDs.base64UUID();
createTimeEpochSecs = System.currentTimeMillis() / 1000;
endTimeEpochSecs = 0;
durationSecs = 0;
// because 0 means never expire, the default is -1
expiresInSecs = -1;
}
public Builder endTime(String endTime, ParseField paramName) {
DateMathParser dateMathParser = new DateMathParser(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER);
try {
endTimeEpochSecs = dateMathParser.parse(endTime, System::currentTimeMillis) / 1000;
} catch (Exception e) {
String msg = Messages.getMessage(Messages.REST_INVALID_DATETIME_PARAMS, paramName.getPreferredName(), endTime);
throw new ElasticsearchParseException(msg, e);
}
return this;
}
public Builder duration(TimeValue duration) {
durationSecs = duration.seconds();
return this;
@ -133,11 +102,7 @@ public class ForecastParams {
}
public ForecastParams build() {
if (endTimeEpochSecs != 0 && durationSecs != 0) {
throw new ElasticsearchParseException(Messages.getMessage(Messages.REST_INVALID_DURATION_AND_ENDTIME));
}
return new ForecastParams(forecastId, createTimeEpochSecs, endTimeEpochSecs, durationSecs, expiresInSecs);
return new ForecastParams(forecastId, createTimeEpochSecs, durationSecs, expiresInSecs);
}
}
}

View File

@ -155,9 +155,6 @@ public class ControlMsgToProcessWriter {
builder.field("forecast_id", params.getForecastId());
builder.field("create_time", params.getCreateTime());
if (params.getEndTime() != 0) {
builder.field("end_time", params.getEndTime());
}
if (params.getDuration() != 0) {
builder.field("duration", params.getDuration());
}

View File

@ -40,9 +40,6 @@ public class RestForecastJobAction extends BaseRestHandler {
request = ForecastJobAction.Request.parseRequest(jobId, parser);
} else {
request = new ForecastJobAction.Request(restRequest.param(Job.ID.getPreferredName()));
if (restRequest.hasParam(ForecastJobAction.Request.END_TIME.getPreferredName())) {
request.setEndTime(restRequest.param(ForecastJobAction.Request.END_TIME.getPreferredName()));
}
if (restRequest.hasParam(ForecastJobAction.Request.DURATION.getPreferredName())) {
request.setDuration(restRequest.param(ForecastJobAction.Request.DURATION.getPreferredName()));
}

View File

@ -1,231 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.transport;
import org.apache.lucene.util.IOUtils;
import org.elasticsearch.Version;
import org.elasticsearch.action.Action;
import org.elasticsearch.common.io.FileSystemUtils;
import org.elasticsearch.common.io.PathUtils;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.reindex.ReindexPlugin;
import org.elasticsearch.license.Licensing;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.test.discovery.TestZenDiscovery;
import org.elasticsearch.xpack.XPackPlugin;
import org.elasticsearch.xpack.deprecation.Deprecation;
import org.elasticsearch.xpack.sql.plugin.SqlPlugin;
import org.junit.BeforeClass;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static java.util.Collections.unmodifiableSet;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.is;
@ClusterScope(numClientNodes = 0, supportsDedicatedMasters = false, numDataNodes = 1)
public class KnownActionsTests extends SecurityIntegTestCase {
private static Set<String> knownActions;
private static Set<String> knownHandlers;
private static Set<String> codeActions;
@Override
protected Collection<Class<? extends Plugin>> getMockPlugins() {
Collection<Class<? extends Plugin>> mockPlugins = super.getMockPlugins();
// no handler wrapping here we check the requestHandlers below and this plugin wraps it
return mockPlugins.stream().filter(p -> p != AssertingTransportInterceptor.TestPlugin.class).collect(Collectors.toList());
}
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder().put(super.nodeSettings(nodeOrdinal))
.put(TestZenDiscovery.USE_MOCK_PINGS.getKey(), false).build();
}
@BeforeClass
public static void init() throws Exception {
knownActions = loadKnownActions();
knownHandlers = loadKnownHandlers();
codeActions = loadCodeActions();
}
public void testAllTransportHandlersAreKnown() {
TransportService transportService = internalCluster().getDataNodeInstance(TransportService.class);
for (String handler : transportService.requestHandlers.keySet()) {
if (!knownActions.contains(handler)) {
assertThat("elasticsearch core transport handler [" + handler + "] is unknown to security", knownHandlers,
hasItem(handler));
}
}
}
public void testAllCodeActionsAreKnown() throws Exception {
for (String action : codeActions) {
assertThat("classpath action [" + action + "] is unknown to security", knownActions, hasItem(action));
}
}
public void testAllKnownActionsAreValid() {
for (String knownAction : knownActions) {
assertThat("security known action [" + knownAction + "] is not among the classpath actions", codeActions,
hasItems(knownAction));
}
}
public void testAllKnownTransportHandlersAreValid() {
TransportService transportService = internalCluster().getDataNodeInstance(TransportService.class);
for (String knownHandler : knownHandlers) {
assertThat("security known handler [" + knownHandler + "] is unknown to core", transportService.requestHandlers.keySet(),
hasItems(knownHandler));
}
}
public static Set<String> loadKnownActions() {
return readSetFromResource("actions");
}
public static Set<String> loadKnownHandlers() {
return readSetFromResource("handlers");
}
private static Set<String> readSetFromResource(String resource) {
Set<String> knownActions = new HashSet<>();
try (InputStream input = KnownActionsTests.class.getResourceAsStream(resource)) {
Streams.readAllLines(input, action -> knownActions.add(action));
} catch (IOException ioe) {
throw new IllegalStateException("could not load known " + resource, ioe);
}
return unmodifiableSet(knownActions);
}
private static Set<String> loadCodeActions() throws IOException, ReflectiveOperationException, URISyntaxException {
Set<String> actions = new HashSet<>();
// loading es core actions in org.elasticsearch package
loadActions(collectSubClasses(Action.class, Version.class), actions);
// loading all xpack top level actions in org.elasticsearch.xpack package
loadActions(collectSubClasses(Action.class, XPackPlugin.class), actions);
// also loading all actions from the licensing plugin in org.elasticsearch.license package
loadActions(collectSubClasses(Action.class, Licensing.class), actions);
// also load stuff from Reindex in org.elasticsearch.index.reindex package
loadActions(collectSubClasses(Action.class, ReindexPlugin.class), actions);
// also load stuff from Deprecation in org.elasticsearch.deprecation
loadActions(collectSubClasses(Action.class, Deprecation.class), actions);
// also load all action from SQL plugin in org.elasticsearch.xpack.sql.plugin package
loadActions(collectSubClasses(Action.class, SqlPlugin.class), actions);
return unmodifiableSet(actions);
}
private static void loadActions(Collection<Class<?>> clazzes, Set<String> actions) throws ReflectiveOperationException {
for (Class<?> clazz : clazzes) {
if (!Modifier.isAbstract(clazz.getModifiers())) {
Field field = null;
try {
field = clazz.getField("INSTANCE");
} catch (NoSuchFieldException nsfe) {
fail("every action should have a static field called INSTANCE, missing in " + clazz.getName());
}
assertThat("every action should have a static field called INSTANCE, present but not static in " + clazz.getName(),
Modifier.isStatic(field.getModifiers()), is(true));
actions.add(((Action) field.get(null)).name());
}
}
}
/**
* finds all subclasses extending {@code subClass}, recursively from the package and codesource of {@code prototype}
*/
private static Collection<Class<?>> collectSubClasses(Class<?> subClass, Class<?> prototype) throws IOException,
ReflectiveOperationException, URISyntaxException {
URL codeLocation = prototype.getProtectionDomain().getCodeSource().getLocation();
final FileSystem fileSystem;
final Path root;
if (codeLocation.toURI().toString().endsWith(".jar")) {
try {
// hack around a bug in the zipfilesystem implementation before java 9,
// its checkWritable was incorrect and it won't work without write permissions.
// if we add the permission, it will open jars r/w, which is too scary! so copy to a safe r-w location.
Path tmp = createTempFile(null, ".jar");
try (InputStream in = FileSystemUtils.openFileURLStream(codeLocation)) {
Files.copy(in, tmp, StandardCopyOption.REPLACE_EXISTING);
}
fileSystem = FileSystems.newFileSystem(new URI("jar:" + tmp.toUri()), Collections.<String,Object>emptyMap());
root = fileSystem.getPath("/");
} catch (URISyntaxException e) {
throw new IOException("couldn't open zipfilesystem: ", e);
}
} else {
fileSystem = null;
root = PathUtils.get(codeLocation.toURI());
}
ClassLoader loader = prototype.getClassLoader();
List<Class<?>> clazzes = new ArrayList<>();
try {
collectClassesForPackage(subClass, root, loader, prototype.getPackage().getName(), clazzes);
} finally {
IOUtils.close(fileSystem);
}
return clazzes;
}
private static void collectClassesForPackage(Class<?> subclass, Path root, ClassLoader cld, String pckgname, List<Class<?>> classes)
throws IOException, ReflectiveOperationException {
String pathName = pckgname.replace('.', '/');
Path directory = root.resolve(pathName);
try (DirectoryStream<Path> stream = Files.newDirectoryStream(directory)) {
for (Path file : stream) {
if (Files.isDirectory(file)) {
// recurse
String subPackage = pckgname + "." + file.getFileName().toString();
// remove trailing / or whatever
if (subPackage.endsWith(root.getFileSystem().getSeparator())) {
subPackage = subPackage.substring(0, subPackage.length() - root.getFileSystem().getSeparator().length());
}
collectClassesForPackage(subclass, root, cld, subPackage, classes);
}
String fname = file.getFileName().toString();
if (fname.endsWith(".class")) {
String clazzName = fname.substring(0, fname.length() - 6);
Class<?> clazz = Class.forName(pckgname + '.' + clazzName, false, cld);
// Don't run static initializers, as we won't use most of them.
// Java will do that automatically once accessed/instantiated.
if (subclass.isAssignableFrom(clazz)) {
classes.add(clazz);
}
}
}
}
}
}

View File

@ -10,7 +10,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.AbstractStreamableXContentTestCase;
import org.elasticsearch.xpack.ml.action.ForecastJobAction.Request;
import java.time.Instant;
import static org.hamcrest.Matchers.equalTo;
public class ForecastJobActionRequestTests extends AbstractStreamableXContentTestCase<Request> {
@ -27,13 +27,12 @@ public class ForecastJobActionRequestTests extends AbstractStreamableXContentTes
@Override
protected Request createTestInstance() {
Request request = new Request(randomAlphaOfLengthBetween(1, 20));
if (randomBoolean()) {
request.setEndTime(Instant.ofEpochMilli(randomNonNegativeLong()).toString());
}
if (randomBoolean()) {
request.setDuration(TimeValue.timeValueSeconds(randomIntBetween(1, 1_000_000)).getStringRep());
}
if (randomBoolean()) {
request.setExpiresIn(TimeValue.timeValueSeconds(randomIntBetween(0, 1_000_000)).getStringRep());
}
return request;
}
@ -41,4 +40,25 @@ public class ForecastJobActionRequestTests extends AbstractStreamableXContentTes
protected Request createBlankInstance() {
return new Request();
}
public void testSetDuration_GivenZero() {
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new Request().setDuration("0"));
assertThat(e.getMessage(), equalTo("[duration] must be positive: [0ms]"));
}
public void testSetDuration_GivenNegative() {
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new Request().setDuration("-1s"));
assertThat(e.getMessage(), equalTo("[duration] must be positive: [-1]"));
}
public void testSetExpiresIn_GivenZero() {
Request request = new Request();
request.setExpiresIn("0");
assertThat(request.getExpiresIn(), equalTo(TimeValue.ZERO));
}
public void testSetExpiresIn_GivenNegative() {
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new Request().setExpiresIn("-1s"));
assertThat(e.getMessage(), equalTo("[expires_in] must be non-negative: [-1]"));
}
}

View File

@ -384,6 +384,17 @@ public class ScrollDataExtractorTests extends ESTestCase {
expectThrows(SearchPhaseExecutionException.class, () -> extractor.next());
}
public void testSearchPhaseExecutionExceptionOnInitScroll() throws IOException {
TestDataExtractor extractor = new TestDataExtractor(1000L, 2000L);
extractor.setNextResponse(createResponseWithShardFailures());
extractor.setNextResponse(createResponseWithShardFailures());
expectThrows(IOException.class, () -> extractor.next());
assertThat(capturedClearScrollIds.isEmpty(), is(true));
}
public void testDomainSplitScriptField() throws IOException {
SearchSourceBuilder.ScriptField withoutSplit = new SearchSourceBuilder.ScriptField(

View File

@ -537,6 +537,7 @@ public class AutodetectProcessManagerTests extends ESTestCase {
public void testCreate_notEnoughThreads() throws IOException {
Client client = mock(Client.class);
ThreadPool threadPool = mock(ThreadPool.class);
when(threadPool.getThreadContext()).thenReturn(new ThreadContext(Settings.EMPTY));
ExecutorService executorService = mock(ExecutorService.class);
doThrow(new EsRejectedExecutionException("")).when(executorService).submit(any(Runnable.class));
when(threadPool.executor(anyString())).thenReturn(executorService);
@ -610,6 +611,7 @@ public class AutodetectProcessManagerTests extends ESTestCase {
private AutodetectProcessManager createNonSpyManager(String jobId) {
Client client = mock(Client.class);
ThreadPool threadPool = mock(ThreadPool.class);
when(threadPool.getThreadContext()).thenReturn(new ThreadContext(Settings.EMPTY));
ExecutorService executorService = mock(ExecutorService.class);
when(threadPool.executor(anyString())).thenReturn(executorService);
when(threadPool.scheduleWithFixedDelay(any(), any(), any())).thenReturn(mock(ThreadPool.Cancellable.class));
@ -639,6 +641,7 @@ public class AutodetectProcessManagerTests extends ESTestCase {
private AutodetectProcessManager createManager(AutodetectCommunicator communicator, Client client) {
ThreadPool threadPool = mock(ThreadPool.class);
when(threadPool.getThreadContext()).thenReturn(new ThreadContext(Settings.EMPTY));
when(threadPool.executor(anyString())).thenReturn(EsExecutors.newDirectExecutorService());
AutodetectProcessFactory autodetectProcessFactory = mock(AutodetectProcessFactory.class);
AutodetectProcessManager manager = new AutodetectProcessManager(Settings.EMPTY, client,

View File

@ -5,18 +5,14 @@
*/
package org.elasticsearch.xpack.ml.job.process.autodetect.params;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.ml.job.messages.Messages;
import java.util.HashSet;
import java.util.Set;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
public class ForecastParamsTests extends ESTestCase {
@ -31,32 +27,10 @@ public class ForecastParamsTests extends ESTestCase {
assertThat(ids.size(), equalTo(10));
}
public void test_UnparseableEndTimeThrows() {
ElasticsearchParseException e =
ESTestCase.expectThrows(ElasticsearchParseException.class, () -> ForecastParams.builder().endTime("bad", END).build());
assertEquals(Messages.getMessage(Messages.REST_INVALID_DATETIME_PARAMS, "end", "bad"), e.getMessage());
}
public void testFormats() {
assertEquals(10L, ForecastParams.builder().endTime("10000", END).build().getEndTime());
assertEquals(1462096800L, ForecastParams.builder().endTime("2016-05-01T10:00:00Z", END).build().getEndTime());
long nowSecs = System.currentTimeMillis() / 1000;
long end = ForecastParams.builder().endTime("now+2H", END).build().getEndTime();
assertThat(end, greaterThanOrEqualTo(nowSecs + 7200));
assertThat(end, lessThanOrEqualTo(nowSecs + 7200 +1));
}
public void testDurationFormats() {
assertEquals(34678L,
ForecastParams.builder().duration(TimeValue.parseTimeValue("34678s", DURATION.getPreferredName())).build().getDuration());
assertEquals(172800L,
ForecastParams.builder().duration(TimeValue.parseTimeValue("2d", DURATION.getPreferredName())).build().getDuration());
}
public void testDurationEndTimeThrows() {
ElasticsearchParseException e = ESTestCase.expectThrows(ElasticsearchParseException.class, () -> ForecastParams.builder()
.endTime("2016-05-01T10:00:00Z", END).duration(TimeValue.parseTimeValue("33d", DURATION.getPreferredName())).build());
assertEquals(Messages.getMessage(Messages.REST_INVALID_DURATION_AND_ENDTIME), e.getMessage());
}
}

View File

@ -10,37 +10,40 @@ import org.elasticsearch.action.admin.indices.analyze.AnalyzeRequest;
import org.elasticsearch.action.search.ClearScrollAction;
import org.elasticsearch.action.search.ClearScrollRequest;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.transport.KnownActionsTests;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.hamcrest.CoreMatchers.equalTo;
public class SecurityActionMapperTests extends ESTestCase {
public void testThatAllOrdinaryActionsRemainTheSame() {
List<String> actions = new ArrayList<>();
actions.addAll(KnownActionsTests.loadKnownActions());
actions.addAll(KnownActionsTests.loadKnownHandlers());
SecurityActionMapper securityActionMapper = new SecurityActionMapper();
int iterations = randomIntBetween(10, 100);
for (int i = 0; i < iterations; i++) {
String randomAction;
do {
if (randomBoolean()) {
randomAction = randomFrom(actions);
} else {
randomAction = randomAlphaOfLength(randomIntBetween(1, 30));
}
} while (randomAction.equals(ClearScrollAction.NAME) ||
StringBuilder actionNameBuilder = new StringBuilder();
if (randomBoolean()) {
actionNameBuilder.append("indices:");
if (randomBoolean()) {
actionNameBuilder.append("data/");
actionNameBuilder.append(randomBoolean() ? "read" : "write");
actionNameBuilder.append("/");
actionNameBuilder.append(randomAlphaOfLengthBetween(2, 12));
} else {
actionNameBuilder.append(randomBoolean() ? "admin" : "monitor");
actionNameBuilder.append("/");
actionNameBuilder.append(randomAlphaOfLengthBetween(2, 12));
}
} else {
actionNameBuilder.append("cluster:");
actionNameBuilder.append(randomBoolean() ? "admin" : "monitor");
actionNameBuilder.append("/");
actionNameBuilder.append(randomAlphaOfLengthBetween(2, 12));
}
String randomAction = actionNameBuilder.toString();
assumeFalse("Random action is one of the known mapped values: " + randomAction, randomAction.equals(ClearScrollAction.NAME) ||
randomAction.equals(AnalyzeAction.NAME) ||
randomAction.equals(AnalyzeAction.NAME + "[s]"));
assertThat(securityActionMapper.action(randomAction, null), equalTo(randomAction));
}
assertThat(securityActionMapper.action(randomAction, null), equalTo(randomAction));
}
public void testClearScroll() {

View File

@ -522,6 +522,11 @@ public class SecurityIndexSearcherWrapperUnitTests extends ESTestCase {
assertTrue(seenLeaves.add(context.reader().getCoreCacheHelper().getKey()));
return weight.bulkScorer(context);
}
@Override
public boolean isCacheable(LeafReaderContext ctx) {
return true;
}
}
static class CreateScorerOnceQuery extends Query {

View File

@ -21,10 +21,6 @@ import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.interva
import static org.hamcrest.Matchers.is;
public class ActionErrorIntegrationTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean timeWarped() {
return true; // to have control over the execution
}
/**
* This test makes sure that when an action encounters an error it should

View File

@ -35,16 +35,6 @@ import static org.hamcrest.Matchers.is;
"org.elasticsearch.xpack.watcher.WatcherIndexingListener:TRACE")
public class TimeThrottleIntegrationTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean timeWarped() {
return true;
}
@Override
protected boolean enableSecurity() {
return true;
}
public void testTimeThrottle() throws Exception {
String id = randomAlphaOfLength(20);
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch()
@ -73,7 +63,7 @@ public class TimeThrottleIntegrationTests extends AbstractWatcherIntegrationTest
public void testTimeThrottleDefaults() throws Exception {
String id = randomAlphaOfLength(30);
PutWatchResponse putWatchResponse = watcherClientWithWatcherUser().preparePutWatch()
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch()
.setId(id)
.setSource(watchBuilder()
.trigger(schedule(interval("1s")))

View File

@ -168,7 +168,6 @@ public class EmailAttachmentTests extends AbstractWatcherIntegrationTestCase {
tmpBuilder.startObject();
emailAttachments.toXContent(tmpBuilder, ToXContent.EMPTY_PARAMS);
tmpBuilder.endObject();
logger.info("TMP BUILDER {}", tmpBuilder.string());
EmailTemplate.Builder emailBuilder = EmailTemplate.builder().from("_from").to("_to").subject("Subject");
WatchSourceBuilder watchSourceBuilder = watchBuilder()
@ -177,7 +176,6 @@ public class EmailAttachmentTests extends AbstractWatcherIntegrationTestCase {
.condition(AlwaysCondition.INSTANCE)
.addAction("_email", emailAction(emailBuilder).setAuthentication(EmailServer.USERNAME, EmailServer.PASSWORD.toCharArray())
.setAttachments(emailAttachments));
logger.info("TMP WATCHSOURCE {}", watchSourceBuilder.build().getBytes().utf8ToString());
watcherClient.preparePutWatch("_test_id")
.setSource(watchSourceBuilder)

View File

@ -9,18 +9,18 @@ import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.xpack.watcher.common.http.HttpMethod;
import org.elasticsearch.xpack.watcher.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
import org.elasticsearch.xpack.watcher.notification.email.EmailTemplate;
import org.elasticsearch.xpack.watcher.actions.Action;
import org.elasticsearch.xpack.watcher.actions.email.EmailAction;
import org.elasticsearch.xpack.watcher.actions.index.IndexAction;
import org.elasticsearch.xpack.watcher.actions.logging.LoggingAction;
import org.elasticsearch.xpack.watcher.actions.webhook.WebhookAction;
import org.elasticsearch.xpack.watcher.client.WatchSourceBuilder;
import org.elasticsearch.xpack.watcher.common.http.HttpMethod;
import org.elasticsearch.xpack.watcher.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
import org.elasticsearch.xpack.watcher.execution.ActionExecutionMode;
import org.elasticsearch.xpack.watcher.execution.ExecutionState;
import org.elasticsearch.xpack.watcher.notification.email.EmailTemplate;
import org.elasticsearch.xpack.watcher.support.xcontent.ObjectPath;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchRequestBuilder;
@ -51,11 +51,6 @@ import static org.hamcrest.Matchers.equalTo;
public class ActionThrottleTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean timeWarped() {
return true;
}
public void testSingleActionAckThrottle() throws Exception {
WatchSourceBuilder watchSourceBuilder = watchBuilder()
.trigger(schedule(interval("60m")));
@ -185,9 +180,7 @@ public class ActionThrottleTests extends AbstractWatcherIntegrationTestCase {
watcherClient().putWatch(new PutWatchRequest("_id", watchSourceBuilder)).actionGet();
refresh(Watch.INDEX);
if (timeWarped()) {
timeWarp().clock().setTime(new DateTime(DateTimeZone.UTC));
}
timeWarp().clock().setTime(new DateTime(DateTimeZone.UTC));
ExecuteWatchResponse executeWatchResponse = watcherClient().prepareExecuteWatch("_id")
.setTriggerEvent(new ManualTriggerEvent("execute_id",
@ -199,9 +192,7 @@ public class ActionThrottleTests extends AbstractWatcherIntegrationTestCase {
String status = ObjectPath.eval("result.actions.0.status", executeWatchResponse.getRecordSource().getAsMap());
assertThat(status, equalTo("simulated"));
if (timeWarped()) {
timeWarp().clock().fastForwardSeconds(1);
}
timeWarp().clock().fastForwardSeconds(1);
executeWatchResponse = watcherClient().prepareExecuteWatch("_id")
.setTriggerEvent(new ManualTriggerEvent("execute_id",
@ -212,9 +203,7 @@ public class ActionThrottleTests extends AbstractWatcherIntegrationTestCase {
status = ObjectPath.eval("result.actions.0.status", executeWatchResponse.getRecordSource().getAsMap());
assertThat(status, equalTo("throttled"));
if (timeWarped()) {
timeWarp().clock().fastForwardSeconds(5);
}
timeWarp().clock().fastForwardSeconds(5);
assertBusy(() -> {
try {
@ -243,9 +232,7 @@ public class ActionThrottleTests extends AbstractWatcherIntegrationTestCase {
watcherClient().putWatch(new PutWatchRequest("_id", watchSourceBuilder)).actionGet();
refresh(Watch.INDEX);
if (timeWarped()) {
timeWarp().clock().setTime(new DateTime(DateTimeZone.UTC));
}
timeWarp().clock().setTime(new DateTime(DateTimeZone.UTC));
ExecuteWatchResponse executeWatchResponse = watcherClient().prepareExecuteWatch("_id")
.setTriggerEvent(new ManualTriggerEvent("execute_id",
@ -256,9 +243,7 @@ public class ActionThrottleTests extends AbstractWatcherIntegrationTestCase {
String status = ObjectPath.eval("result.actions.0.status", executeWatchResponse.getRecordSource().getAsMap());
assertThat(status, equalTo("simulated"));
if (timeWarped()) {
timeWarp().clock().fastForwardSeconds(1);
}
timeWarp().clock().fastForwardSeconds(1);
executeWatchResponse = watcherClient().prepareExecuteWatch("_id")
.setTriggerEvent(new ManualTriggerEvent("execute_id",
@ -269,9 +254,8 @@ public class ActionThrottleTests extends AbstractWatcherIntegrationTestCase {
status = ObjectPath.eval("result.actions.0.status", executeWatchResponse.getRecordSource().getAsMap());
assertThat(status, equalTo("throttled"));
if (timeWarped()) {
timeWarp().clock().fastForwardSeconds(20);
}
timeWarp().clock().fastForwardSeconds(20);
assertBusy(() -> {
try {
//Since the default throttle period is 5 seconds but we have overridden the period in the watch this should trigger

View File

@ -11,13 +11,13 @@ import org.elasticsearch.env.Environment;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.xpack.ssl.TestsSSLService;
import org.elasticsearch.xpack.watcher.actions.ActionBuilders;
import org.elasticsearch.xpack.watcher.common.http.HttpMethod;
import org.elasticsearch.xpack.watcher.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.watcher.common.http.Scheme;
import org.elasticsearch.xpack.watcher.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
import org.elasticsearch.xpack.ssl.TestsSSLService;
import org.elasticsearch.xpack.watcher.actions.ActionBuilders;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.history.WatchRecord;
import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource;
@ -81,10 +81,8 @@ public class WebhookHttpsIntegrationTests extends AbstractWatcherIntegrationTest
.addAction("_id", ActionBuilders.webhookAction(builder)))
.get();
if (timeWarped()) {
timeWarp().trigger("_id");
refresh();
}
timeWarp().trigger("_id");
refresh();
assertWatchWithMinimumPerformedActionsCount("_id", 1, false);
assertThat(webServer.requests(), hasSize(1));
@ -122,10 +120,8 @@ public class WebhookHttpsIntegrationTests extends AbstractWatcherIntegrationTest
.addAction("_id", ActionBuilders.webhookAction(builder)))
.get();
if (timeWarped()) {
timeWarp().trigger("_id");
refresh();
}
timeWarp().trigger("_id");
refresh();
assertWatchWithMinimumPerformedActionsCount("_id", 1, false);
assertThat(webServer.requests(), hasSize(1));

View File

@ -11,14 +11,15 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.http.HttpServerTransport;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.test.SecuritySettingsSource;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.transport.Netty4Plugin;
import org.elasticsearch.xpack.watcher.actions.ActionBuilders;
import org.elasticsearch.xpack.watcher.common.http.HttpMethod;
import org.elasticsearch.xpack.watcher.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.watcher.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
import org.elasticsearch.xpack.watcher.actions.ActionBuilders;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.history.WatchRecord;
import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource;
@ -26,6 +27,9 @@ import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.junit.After;
import org.junit.Before;
import java.util.ArrayList;
import java.util.Collection;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertExists;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
@ -50,8 +54,10 @@ public class WebhookIntegrationTests extends AbstractWatcherIntegrationTestCase
}
@Override
protected boolean enableSecurity() {
return true;
protected Collection<Class<? extends Plugin>> nodePlugins() {
ArrayList<Class<? extends Plugin>> plugins = new ArrayList<>(super.nodePlugins());
plugins.add(Netty4Plugin.class); // for http
return plugins;
}
@Before
@ -71,6 +77,7 @@ public class WebhookIntegrationTests extends AbstractWatcherIntegrationTestCase
.putParam("param1", new TextTemplate("value1"))
.putParam("watch_id", new TextTemplate("_id"))
.body(new TextTemplate("_body"))
.auth(new BasicAuth("user", "pass".toCharArray()))
.method(HttpMethod.POST);
watcherClient().preparePutWatch("_id")
@ -81,10 +88,8 @@ public class WebhookIntegrationTests extends AbstractWatcherIntegrationTestCase
.addAction("_id", ActionBuilders.webhookAction(builder)))
.get();
if (timeWarped()) {
timeWarp().trigger("_id");
refresh();
}
timeWarp().trigger("_id");
refresh();
assertWatchWithMinimumPerformedActionsCount("_id", 1, false);
assertThat(webServer.requests(), hasSize(1));
@ -123,10 +128,8 @@ public class WebhookIntegrationTests extends AbstractWatcherIntegrationTestCase
.addAction("_id", ActionBuilders.webhookAction(builder)))
.get();
if (timeWarped()) {
timeWarp().trigger("_id");
refresh();
}
timeWarp().trigger("_id");
refresh();
assertWatchWithMinimumPerformedActionsCount("_id", 1, false);
@ -147,7 +150,6 @@ public class WebhookIntegrationTests extends AbstractWatcherIntegrationTestCase
HttpRequestTemplate.Builder builder = HttpRequestTemplate.builder(host, publishAddress.getPort())
.path(new TextTemplate("/%3Clogstash-%7Bnow%2Fd%7D%3E/log/1"))
.body(new TextTemplate("{\"foo\":\"bar\"}"))
.auth(new BasicAuth("test", SecuritySettingsSource.TEST_PASSWORD.toCharArray()))
.putHeader("Content-Type", new TextTemplate("application/json"))
.method(HttpMethod.PUT);

View File

@ -31,11 +31,6 @@ import static org.mockito.Mockito.when;
public class CompareConditionSearchTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean enableSecurity() {
return true;
}
public void testExecuteWithAggs() throws Exception {
client().prepareIndex("my-index", "my-type").setSource("@timestamp", "2005-01-01T00:00").get();
client().prepareIndex("my-index", "my-type").setSource("@timestamp", "2005-01-01T00:10").get();

View File

@ -81,16 +81,6 @@ public class HistoryActionConditionTests extends AbstractWatcherIntegrationTestC
}
@Override
protected boolean timeWarped() {
return true; // just to have better control over the triggers
}
@Override
protected boolean enableSecurity() {
return false; // remove security noise from this test
}
/**
* A hard failure is where an exception is thrown by the script condition.
*/

View File

@ -10,10 +10,10 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.test.junit.annotations.TestLogging;
import org.elasticsearch.xpack.watcher.notification.email.EmailTemplate;
import org.elasticsearch.xpack.watcher.notification.email.support.EmailServer;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.execution.ExecutionState;
import org.elasticsearch.xpack.watcher.notification.email.EmailTemplate;
import org.elasticsearch.xpack.watcher.notification.email.support.EmailServer;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
import org.junit.After;
@ -49,11 +49,6 @@ public class HistoryTemplateEmailMappingsTests extends AbstractWatcherIntegratio
server.stop();
}
@Override
protected boolean timeWarped() {
return true;
}
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder()

View File

@ -63,16 +63,6 @@ public class HistoryTemplateHttpMappingsTests extends AbstractWatcherIntegration
webServer.close();
}
@Override
protected boolean timeWarped() {
return true; // just to have better control over the triggers
}
@Override
protected boolean enableSecurity() {
return false; // remove security noise from this test
}
public void testHttpFields() throws Exception {
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch("_id").setSource(watchBuilder()
.trigger(schedule(interval("5s")))
@ -84,7 +74,6 @@ public class HistoryTemplateHttpMappingsTests extends AbstractWatcherIntegration
.body("_body"))))
.get();
// one for the input, one for the webhook
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("{}"));
webServer.enqueue(new MockResponse().setResponseCode(200).setBody("{}"));

View File

@ -26,15 +26,6 @@ import static org.hamcrest.Matchers.notNullValue;
* not analyzed so they can be used in aggregations
*/
public class HistoryTemplateIndexActionMappingsTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean timeWarped() {
return true; // just to have better control over the triggers
}
@Override
protected boolean enableSecurity() {
return false; // remove security noise from this test
}
public void testIndexActionFields() throws Exception {
String index = "the-index";

View File

@ -32,16 +32,6 @@ import static org.hamcrest.Matchers.notNullValue;
*/
public class HistoryTemplateSearchInputMappingsTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean timeWarped() {
return true; // just to have better control over the triggers
}
@Override
protected boolean enableSecurity() {
return false; // remove security noise from this test
}
public void testHttpFields() throws Exception {
String index = "the-index";
String type = "the-type";

View File

@ -15,7 +15,6 @@ import org.elasticsearch.xpack.watcher.execution.ExecutionState;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
import java.io.IOException;
import java.util.Map;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.extractValue;
@ -31,15 +30,6 @@ import static org.hamcrest.Matchers.notNullValue;
* This test makes sure that the different time fields in the watch_record are mapped as date types
*/
public class HistoryTemplateTimeMappingsTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean timeWarped() {
return true; // just to have better control over the triggers
}
@Override
protected boolean enableSecurity() {
return false; // remove security noise from this test
}
public void testTimeFields() throws Exception {
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch("_id").setSource(watchBuilder()

View File

@ -11,17 +11,14 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.SecuritySettingsSource;
import org.elasticsearch.transport.Netty4Plugin;
import org.elasticsearch.xpack.watcher.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.watcher.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.watcher.input.http.HttpInput;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
@ -60,9 +57,8 @@ public class ChainIntegrationTests extends AbstractWatcherIntegrationTestCase {
InetSocketAddress address = internalCluster().httpAddresses()[0];
HttpInput.Builder httpInputBuilder = httpInput(HttpRequestTemplate.builder(address.getHostString(), address.getPort())
.path("/" + index + "/_search")
.body(jsonBuilder().startObject().field("size", 1).endObject().string())
.auth(securityEnabled() ? new BasicAuth("test", SecuritySettingsSource.TEST_PASSWORD.toCharArray()) : null));
.path("/" + index + "/_search")
.body(jsonBuilder().startObject().field("size", 1).endObject().string()));
ChainInput.Builder chainedInputBuilder = chainInput()
.add("first", simpleInput("url", "/" + index + "/_search"))
@ -75,12 +71,8 @@ public class ChainIntegrationTests extends AbstractWatcherIntegrationTestCase {
.addAction("indexAction", indexAction("my-index", "my-type")))
.get();
if (timeWarped()) {
timeWarp().trigger("_name");
refresh();
} else {
assertBusy(() -> assertWatchExecuted(), 9, TimeUnit.SECONDS);
}
timeWarp().trigger("_name");
refresh();
assertWatchWithMinimumPerformedActionsCount("_name", 1, false);
}

View File

@ -12,13 +12,11 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.SecuritySettingsSource;
import org.elasticsearch.test.junit.annotations.TestLogging;
import org.elasticsearch.transport.Netty4Plugin;
import org.elasticsearch.xpack.watcher.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.watcher.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
import org.elasticsearch.xpack.watcher.client.WatcherClient;
import org.elasticsearch.xpack.watcher.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
import org.elasticsearch.xpack.watcher.condition.CompareCondition;
import org.elasticsearch.xpack.watcher.history.HistoryStore;
import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource;
@ -54,11 +52,6 @@ public class HttpInputIntegrationTests extends AbstractWatcherIntegrationTestCas
.build();
}
@Override
protected boolean timeWarped() {
return true;
}
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
ArrayList<Class<? extends Plugin>> plugins = new ArrayList<>(super.nodePlugins());
@ -77,9 +70,7 @@ public class HttpInputIntegrationTests extends AbstractWatcherIntegrationTestCas
.input(httpInput(HttpRequestTemplate.builder(address.getHostString(), address.getPort())
.path("/index/_search")
.body(jsonBuilder().startObject().field("size", 1).endObject().string())
.putHeader("Content-Type", new TextTemplate("application/json"))
.auth(securityEnabled() ? new BasicAuth("test", SecuritySettingsSource.TEST_PASSWORD.toCharArray())
: null)))
.putHeader("Content-Type", new TextTemplate("application/json"))))
.condition(new CompareCondition("ctx.payload.hits.total", CompareCondition.Op.EQ, 1L))
.addAction("_id", loggingAction("anything")))
.get();
@ -94,10 +85,7 @@ public class HttpInputIntegrationTests extends AbstractWatcherIntegrationTestCas
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch("_name")
.setSource(watchBuilder()
.trigger(schedule(interval("1s")))
.input(httpInput(HttpRequestTemplate.builder(address.getHostString(), address.getPort())
.path("/_cluster/stats")
.auth(securityEnabled() ? new BasicAuth("test", SecuritySettingsSource.TEST_PASSWORD.toCharArray())
: null)))
.input(httpInput(HttpRequestTemplate.builder(address.getHostString(), address.getPort()).path("/_cluster/stats")))
.condition(new CompareCondition("ctx.payload.nodes.count.total", CompareCondition.Op.GTE, 1L))
.addAction("_id", loggingAction("anything")))
.get();
@ -122,9 +110,6 @@ public class HttpInputIntegrationTests extends AbstractWatcherIntegrationTestCas
HttpRequestTemplate.Builder requestBuilder = HttpRequestTemplate.builder(address.getHostString(), address.getPort())
.path(new TextTemplate("/idx/_search"))
.body(body.string());
if (securityEnabled()) {
requestBuilder.auth(new BasicAuth("test", SecuritySettingsSource.TEST_PASSWORD.toCharArray()));
}
watcherClient.preparePutWatch("_name1")
.setSource(watchBuilder()

View File

@ -1,149 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.watcher.security;
import org.elasticsearch.test.SecuritySettingsSource;
import org.elasticsearch.xpack.watcher.WatcherState;
import org.elasticsearch.xpack.watcher.client.WatcherClient;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.delete.DeleteWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.get.GetWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.stats.WatcherStatsResponse;
import org.elasticsearch.xpack.watcher.trigger.TriggerEvent;
import org.elasticsearch.xpack.watcher.trigger.schedule.IntervalSchedule;
import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTriggerEvent;
import org.joda.time.DateTime;
import java.util.Collections;
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken
.BASIC_AUTH_HEADER;
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken
.basicAuthHeaderValue;
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;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.core.Is.is;
import static org.joda.time.DateTimeZone.UTC;
public class BasicSecurityTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean enableSecurity() {
return true;
}
public void testNoAuthorization() throws Exception {
String basicAuth = basicAuthHeaderValue("transport_client", SecuritySettingsSource.TEST_PASSWORD_SECURE_STRING);
WatcherClient watcherClient = watcherClient().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuth));
Exception e = expectThrows(Exception.class, () -> watcherClient.prepareWatcherStats().get());
assertThat(e.getMessage(),
equalTo("action [cluster:monitor/xpack/watcher/stats/dist] is unauthorized for user [transport_client]"));
}
public void testWatcherMonitorRole() throws Exception {
// stats and get watch apis require at least monitor role:
String token = basicAuthHeaderValue("test", SecuritySettingsSource.TEST_PASSWORD_SECURE_STRING);
try {
watcherClient().filterWithHeader(Collections.singletonMap("Authorization", token)).prepareWatcherStats()
.get();
fail("authentication failure should have occurred");
} catch (Exception e) {
assertThat(e.getMessage(), equalTo("action [cluster:monitor/xpack/watcher/stats/dist] is unauthorized for user [test]"));
}
try {
watcherClient().filterWithHeader(Collections.singletonMap("Authorization", token)).prepareGetWatch("_id")
.get();
fail("authentication failure should have occurred");
} catch (Exception e) {
assertThat(e.getMessage(), equalTo("action [cluster:monitor/xpack/watcher/watch/get] is unauthorized for user [test]"));
}
// stats and get watch are allowed by role monitor:
token = basicAuthHeaderValue("monitor", SecuritySettingsSource.TEST_PASSWORD_SECURE_STRING);
WatcherStatsResponse statsResponse = watcherClient().filterWithHeader(Collections.singletonMap("Authorization", token))
.prepareWatcherStats().get();
boolean watcherStarted = statsResponse.getNodes().stream().anyMatch(node -> node.getWatcherState() == WatcherState.STARTED);
assertThat(watcherStarted, is(true));
GetWatchResponse getWatchResponse = watcherClient().filterWithHeader(Collections.singletonMap("Authorization", token))
.prepareGetWatch("_id").get();
assertThat(getWatchResponse.isFound(), is(false));
// but put watch isn't allowed by monitor:
try {
watcherClient().filterWithHeader(Collections.singletonMap("Authorization", token)).preparePutWatch("_id")
.setSource(watchBuilder().trigger(schedule(interval(5, IntervalSchedule.Interval.Unit.SECONDS))))
.get();
fail("authentication failure should have occurred");
} catch (Exception e) {
assertThat(e.getMessage(), equalTo("action [cluster:admin/xpack/watcher/watch/put] is unauthorized for user [monitor]"));
}
}
public void testWatcherAdminRole() throws Exception {
// put, execute and delete watch apis requires watcher admin role:
String token = basicAuthHeaderValue("test", SecuritySettingsSource.TEST_PASSWORD_SECURE_STRING);
try {
watcherClient().filterWithHeader(Collections.singletonMap("Authorization", token)).preparePutWatch("_id")
.setSource(watchBuilder().trigger(schedule(interval(5, IntervalSchedule.Interval.Unit.SECONDS))))
.get();
fail("authentication failure should have occurred");
} catch (Exception e) {
assertThat(e.getMessage(), equalTo("action [cluster:admin/xpack/watcher/watch/put] is unauthorized for user [test]"));
}
TriggerEvent triggerEvent = new ScheduleTriggerEvent(new DateTime(UTC), new DateTime(UTC));
try {
watcherClient().filterWithHeader(Collections.singletonMap("Authorization", token)).prepareExecuteWatch("_id")
.setTriggerEvent(triggerEvent)
.get();
fail("authentication failure should have occurred");
} catch (Exception e) {
assertThat(e.getMessage(), equalTo("action [cluster:admin/xpack/watcher/watch/execute] is unauthorized for user [test]"));
}
try {
watcherClient().filterWithHeader(Collections.singletonMap("Authorization", token)).prepareDeleteWatch("_id")
.get();
fail("authentication failure should have occurred");
} catch (Exception e) {
assertThat(e.getMessage(), equalTo("action [cluster:admin/xpack/watcher/watch/delete] is unauthorized for user [test]"));
}
// put, execute and delete watch apis are allowed by role admin:
token = basicAuthHeaderValue("admin", SecuritySettingsSource.TEST_PASSWORD_SECURE_STRING);
PutWatchResponse putWatchResponse = watcherClient().filterWithHeader(Collections.singletonMap("Authorization", token))
.preparePutWatch("_id")
.setSource(watchBuilder().trigger(schedule(interval(5, IntervalSchedule.Interval.Unit.SECONDS))))
.get();
assertThat(putWatchResponse.getVersion(), equalTo(1L));
ExecuteWatchResponse executeWatchResponse = watcherClient().filterWithHeader(Collections.singletonMap("Authorization", token))
.prepareExecuteWatch("_id")
.setTriggerEvent(triggerEvent)
.get();
DeleteWatchResponse deleteWatchResponse = watcherClient().filterWithHeader(Collections.singletonMap("Authorization", token))
.prepareDeleteWatch("_id")
.get();
assertThat(deleteWatchResponse.getVersion(), equalTo(2L));
assertThat(deleteWatchResponse.isFound(), is(true));
// stats and get watch are also allowed by role monitor:
token = basicAuthHeaderValue("admin",SecuritySettingsSource.TEST_PASSWORD_SECURE_STRING);
WatcherStatsResponse statsResponse = watcherClient().filterWithHeader(Collections.singletonMap("Authorization", token))
.prepareWatcherStats()
.get();
boolean watcherStarted = statsResponse.getNodes().stream().anyMatch(node -> node.getWatcherState() == WatcherState.STARTED);
assertThat(watcherStarted, is(true));
GetWatchResponse getWatchResponse = watcherClient().filterWithHeader(Collections.singletonMap("Authorization", token))
.prepareGetWatch("_id")
.get();
assertThat(getWatchResponse.isFound(), is(false));
}
}

View File

@ -5,7 +5,6 @@
*/
package org.elasticsearch.xpack.watcher.test;
import io.netty.util.internal.SystemPropertyUtil;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesResponse;
@ -13,18 +12,14 @@ import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.analysis.common.CommonAnalysisPlugin;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.routing.IndexRoutingTable;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentHelper;
@ -41,8 +36,6 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.elasticsearch.test.InternalTestCluster;
import org.elasticsearch.test.SecuritySettingsSource;
import org.elasticsearch.test.TestCluster;
import org.elasticsearch.test.disruption.ServiceDisruptionScheme;
import org.elasticsearch.test.store.MockFSIndexStore;
import org.elasticsearch.test.transport.MockTransportService;
@ -52,8 +45,6 @@ import org.elasticsearch.xpack.XPackPlugin;
import org.elasticsearch.xpack.XPackSettings;
import org.elasticsearch.xpack.ml.MachineLearning;
import org.elasticsearch.xpack.security.Security;
import org.elasticsearch.xpack.security.authc.file.FileRealm;
import org.elasticsearch.xpack.security.authc.support.Hasher;
import org.elasticsearch.xpack.template.TemplateUtils;
import org.elasticsearch.xpack.watcher.WatcherState;
import org.elasticsearch.xpack.watcher.client.WatcherClient;
@ -74,16 +65,8 @@ import org.hamcrest.Matcher;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Arrays;
@ -96,14 +79,12 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.elasticsearch.test.ESIntegTestCase.Scope.SUITE;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.elasticsearch.xpack.watcher.support.WatcherIndexTemplateRegistry.HISTORY_TEMPLATE_NAME;
import static org.elasticsearch.xpack.watcher.support.WatcherIndexTemplateRegistry.TRIGGERED_TEMPLATE_NAME;
import static org.elasticsearch.xpack.watcher.support.WatcherIndexTemplateRegistry.WATCHES_TEMPLATE_NAME;
@ -120,66 +101,33 @@ public abstract class AbstractWatcherIntegrationTestCase extends ESIntegTestCase
public static final String WATCHER_LANG = Script.DEFAULT_SCRIPT_LANG;
private static final boolean timeWarpEnabled = SystemPropertyUtil.getBoolean("tests.timewarp", true);
private TimeWarp timeWarp;
private static Boolean securityEnabled;
@Override
protected TestCluster buildTestCluster(Scope scope, long seed) throws IOException {
if (securityEnabled == null) {
securityEnabled = enableSecurity();
}
return super.buildTestCluster(scope, seed);
}
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
//TODO: for now lets isolate watcher tests from monitoring (randomize this later)
.put(XPackSettings.MONITORING_ENABLED.getKey(), false)
.put(XPackSettings.SECURITY_ENABLED.getKey(), false)
// we do this by default in core, but for watcher this isn't needed and only adds noise.
.put("index.store.mock.check_index_on_close", false)
// watcher settings that should work despite randomization
.put("xpack.watcher.execution.scroll.size", randomIntBetween(1, 100))
.put("xpack.watcher.watch.scroll.size", randomIntBetween(1, 100))
.put(SecuritySettings.settings(securityEnabled))
// Disable native ML autodetect_process as the c++ controller won't be available
.put(MachineLearning.AUTODETECT_PROCESS.getKey(), false)
//.put(NetworkModule.TRANSPORT_TYPE_KEY, Security.NAME4)
//.put(NetworkModule.HTTP_TYPE_KEY, Security.NAME4)
.build();
}
@Override
protected Path nodeConfigPath(final int nodeOrdinal) {
if (!securityEnabled) {
return null;
}
final Path conf = createTempDir().resolve("watcher_security");
final Path xpackConf = conf.resolve(XPackPlugin.NAME);
try {
Files.createDirectories(xpackConf);
writeFile(xpackConf, "users", SecuritySettings.USERS);
writeFile(xpackConf, "users_roles", SecuritySettings.USER_ROLES);
writeFile(xpackConf, "roles.yml", SecuritySettings.ROLES);
} catch (final IOException e) {
throw new UncheckedIOException(e);
}
return conf;
}
private static void writeFile(final Path folder, final String name, final String content) throws IOException {
final Path file = folder.resolve(name);
try (BufferedWriter stream = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) {
Streams.copy(content, stream);
}
}
public static void writeFile(final Path folder, final String name, final byte[] content) throws IOException {
final Path file = folder.resolve(name);
try (OutputStream stream = Files.newOutputStream(file)) {
Streams.copy(content, stream);
}
protected Settings transportClientSettings() {
return Settings.builder()
.put("client.transport.sniff", false)
.put(NetworkModule.TRANSPORT_TYPE_KEY, Security.NAME4)
.put(NetworkModule.HTTP_TYPE_KEY, Security.NAME4)
.build();
}
@Override
@ -211,23 +159,6 @@ public abstract class AbstractWatcherIntegrationTestCase extends ESIntegTestCase
return nodePlugins();
}
@Override
protected Function<Client,Client> getClientWrapper() {
if (securityEnabled == false) {
return Function.identity();
}
Map<String, String> headers = Collections.singletonMap("Authorization",
basicAuthHeaderValue(SecuritySettings.TEST_USERNAME, new SecureString(SecuritySettings.TEST_PASSWORD.toCharArray())));
// we need to wrap node clients because we do not specify a user for nodes and all requests will use the system
// user. This is ok for internal n2n stuff but the test framework does other things like wiping indices, repositories, etc
// that the system user cannot do. so we wrap the node client with a user that can do these things since the client() calls
// are randomized to return both node clients and transport clients
// transport clients do not need to be wrapped since we specify the xpack.security.user setting that sets the default user to be
// used for the transport client. If we did not set a default user then the transport client would not even be allowed
// to connect
return client -> (client instanceof NodeClient) ? client.filterWithHeader(headers) : client;
}
protected List<Class<? extends Plugin>> pluginTypes() {
List<Class<? extends Plugin>> types = new ArrayList<>();
if (timeWarped()) {
@ -246,26 +177,15 @@ public abstract class AbstractWatcherIntegrationTestCase extends ESIntegTestCase
* this method can be overridden.
*/
protected boolean timeWarped() {
return timeWarpEnabled;
}
/**
* @return whether security has been enabled
*/
protected final boolean securityEnabled() {
return securityEnabled;
}
/**
* Override and returns {@code false} to force running without security
*/
protected boolean enableSecurity() {
return randomBoolean();
return true;
}
@Before
public void _setup() throws Exception {
setupTimeWarp();
if (timeWarped()) {
timeWarp = new TimeWarp(internalCluster().getInstances(ScheduleTriggerEngineMock.class),
(ClockMock)getInstanceFromMaster(Clock.class));
}
startWatcherIfNodesExist();
createWatcherIndicesOrAliases();
}
@ -277,32 +197,6 @@ public abstract class AbstractWatcherIntegrationTestCase extends ESIntegTestCase
stopWatcher();
}
@AfterClass
public static void _cleanupClass() {
securityEnabled = null;
}
@Override
protected Settings transportClientSettings() {
if (securityEnabled == false) {
return super.transportClientSettings();
}
return Settings.builder()
.put("client.transport.sniff", false)
.put(Security.USER_SETTING.getKey(), "admin:" + SecuritySettingsSource.TEST_PASSWORD)
.put(NetworkModule.TRANSPORT_TYPE_KEY, Security.NAME4)
.put(NetworkModule.HTTP_TYPE_KEY, Security.NAME4)
.build();
}
private void setupTimeWarp() throws Exception {
if (timeWarped()) {
timeWarp = new TimeWarp(internalCluster().getInstances(ScheduleTriggerEngineMock.class),
(ClockMock)getInstanceFromMaster(Clock.class));
}
}
private void startWatcherIfNodesExist() throws Exception {
if (internalCluster().size() > 0) {
ensureLicenseEnabled();
@ -435,27 +329,10 @@ public abstract class AbstractWatcherIntegrationTestCase extends ESIntegTestCase
}
protected WatcherClient watcherClient() {
Client client = securityEnabled ? internalCluster().transportClient() : client();
return randomBoolean() ? new XPackClient(client).watcher() : new WatcherClient(client);
return randomBoolean() ? new XPackClient(client()).watcher() : new WatcherClient(client());
}
/**
* This watcher client needs to be used whenenver an index action is about to be called in a watch
* as otherwise there is no permission to index data with the default transport client user called admin
* This is important if the watch is executed, as the watch is run as the user who stored the watch
* when security is enabled
*/
protected WatcherClient watcherClientWithWatcherUser() {
if (securityEnabled) {
return watcherClient()
.filterWithHeader(Collections.singletonMap("Authorization",
basicAuthHeaderValue("watcher_test", new SecureString(SecuritySettings.TEST_PASSWORD.toCharArray()))));
} else {
return watcherClient();
}
}
protected IndexNameExpressionResolver indexNameExpressionResolver() {
private IndexNameExpressionResolver indexNameExpressionResolver() {
return internalCluster().getInstance(IndexNameExpressionResolver.class);
}
@ -681,74 +558,6 @@ public abstract class AbstractWatcherIntegrationTestCase extends ESIntegTestCase
}
}
/** Security related settings */
public static class SecuritySettings {
public static final String TEST_USERNAME = "test";
public static final String TEST_PASSWORD = SecuritySettingsSource.TEST_PASSWORD;
private static final String TEST_PASSWORD_HASHED = new String(Hasher.BCRYPT.hash(new SecureString(TEST_PASSWORD.toCharArray())));
static boolean auditLogsEnabled = SystemPropertyUtil.getBoolean("tests.audit_logs", true);
public static final String USERS =
"transport_client:" + TEST_PASSWORD_HASHED + "\n" +
TEST_USERNAME + ":" + TEST_PASSWORD_HASHED + "\n" +
"admin:" + TEST_PASSWORD_HASHED + "\n" +
"watcher_test:" + TEST_PASSWORD_HASHED + "\n" +
"monitor:" + TEST_PASSWORD_HASHED;
public static final String USER_ROLES =
"transport_client:transport_client\n" +
"test:test\n" +
"admin:admin\n" +
"monitor:monitor\n" +
"watcher_test:watcher_test,watcher_admin,watcher_user\n";
public static final String ROLES =
"test:\n" + // a user for the test infra.
" cluster: [ 'cluster:monitor/nodes/info', 'cluster:monitor/state', 'cluster:monitor/health', 'cluster:monitor/stats'," +
" 'cluster:admin/settings/update', 'cluster:admin/repository/delete', 'cluster:monitor/nodes/liveness'," +
" 'indices:admin/template/get', 'indices:admin/template/put', 'indices:admin/template/delete'," +
" 'cluster:admin/script/put', 'cluster:monitor/task' ]\n" +
" indices:\n" +
" - names: '*'\n" +
" privileges: [ all ]\n" +
"\n" +
"admin:\n" +
" cluster: [ 'manage' ]\n" +
"\n" +
"monitor:\n" +
" cluster: [ 'monitor' ]\n" +
"\n" +
"watcher_test:\n" +
" cluster: [ 'manage_watcher', 'cluster:admin/xpack/watcher/watch/put' ]\n" +
" indices:\n" +
" - names: 'my_watcher_index'\n" +
" privileges: [ all ]\n"
;
public static Settings settings(boolean enabled) {
Settings.Builder builder = Settings.builder();
if (!enabled) {
return builder.put("xpack.security.enabled", false).build();
}
builder.put("xpack.security.enabled", true)
.put("xpack.security.authc.realms.esusers.type", FileRealm.TYPE)
.put("xpack.security.authc.realms.esusers.order", 0)
.put("xpack.security.audit.enabled", auditLogsEnabled);
/*
* Security should always use one of its transports so if it is enabled explicitly declare one otherwise a local transport could
* be used.
*/
builder.put(NetworkModule.TRANSPORT_TYPE_KEY, Security.NAME4);
builder.put(NetworkModule.HTTP_TYPE_KEY, Security.NAME4);
return builder.build();
}
}
/**
* A disruption that prevents time from advancing on nodes. This is needed to allow time sensitive tests
* to have full control of time. This disruption requires {@link ClockMock} being available on the nodes.
@ -815,4 +624,4 @@ public abstract class AbstractWatcherIntegrationTestCase extends ESIntegTestCase
return "time frozen";
}
}
}
}

View File

@ -63,16 +63,6 @@ import static org.hamcrest.Matchers.notNullValue;
"org.elasticsearch.xpack.watcher.WatcherIndexingListener:TRACE")
public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean enableSecurity() {
return false;
}
@Override
protected boolean timeWarped() {
return true;
}
public void testIndexWatch() throws Exception {
WatcherClient watcherClient = watcherClient();
createIndex("idx");
@ -114,11 +104,9 @@ public class BasicWatcherTests extends AbstractWatcherIntegrationTestCase {
client().prepareIndex("idx", "type").setSource("field", "value").get();
refresh();
if (timeWarped()) {
timeWarp().clock().fastForwardSeconds(5);
timeWarp().trigger("_name");
refresh();
}
timeWarp().clock().fastForwardSeconds(5);
timeWarp().trigger("_name");
refresh();
assertWatchWithMinimumPerformedActionsCount("_name", 1);
}

View File

@ -63,11 +63,6 @@ public class BootStrapTests extends AbstractWatcherIntegrationTestCase {
return false;
}
@Override
protected boolean enableSecurity() {
return false;
}
@Before
public void deleteAllWatchHistoryIndices() {
assertAcked(client().admin().indices().prepareDelete(HistoryStore.INDEX_PREFIX + "*"));

View File

@ -36,11 +36,6 @@ import static org.hamcrest.Matchers.notNullValue;
public class ExecutionVarsIntegrationTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean timeWarped() {
return true;
}
@Override
protected List<Class<? extends Plugin>> pluginTypes() {
List<Class<? extends Plugin>> types = super.pluginTypes();

View File

@ -42,12 +42,6 @@ import static org.hamcrest.Matchers.nullValue;
public class HistoryIntegrationTests extends AbstractWatcherIntegrationTestCase {
// FOR TESTING
@Override
protected boolean enableSecurity() {
return false;
}
// issue: https://github.com/elastic/x-plugins/issues/2338
public void testThatHistoryIsWrittenWithChainedInput() throws Exception {
XContentBuilder xContentBuilder = jsonBuilder().startObject().startObject("inner").field("date", "2015-06-06").endObject()

View File

@ -9,12 +9,12 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.junit.annotations.Network;
import org.elasticsearch.xpack.watcher.actions.pagerduty.PagerDutyAction;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.notification.pagerduty.IncidentEvent;
import org.elasticsearch.xpack.watcher.notification.pagerduty.IncidentEventContext;
import org.elasticsearch.xpack.watcher.notification.pagerduty.PagerDutyAccount;
import org.elasticsearch.xpack.watcher.notification.pagerduty.PagerDutyService;
import org.elasticsearch.xpack.watcher.notification.pagerduty.SentEvent;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
import org.elasticsearch.xpack.watcher.watch.Payload;
@ -35,16 +35,6 @@ import static org.hamcrest.Matchers.notNullValue;
@Network
public class PagerDutyServiceTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean timeWarped() {
return true;
}
@Override
protected boolean enableSecurity() {
return false;
}
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder()

View File

@ -12,13 +12,13 @@ import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.test.junit.annotations.Network;
import org.elasticsearch.xpack.watcher.actions.slack.SlackAction;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.notification.slack.SentMessages;
import org.elasticsearch.xpack.watcher.notification.slack.SlackAccount;
import org.elasticsearch.xpack.watcher.notification.slack.SlackService;
import org.elasticsearch.xpack.watcher.notification.slack.message.Attachment;
import org.elasticsearch.xpack.watcher.notification.slack.message.SlackMessage;
import org.elasticsearch.xpack.watcher.actions.slack.SlackAction;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
@ -42,15 +42,6 @@ import static org.hamcrest.Matchers.nullValue;
@Network
public class SlackServiceTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean timeWarped() {
return true;
}
@Override
protected boolean enableSecurity() {
return false;
}
@Override
protected Settings nodeSettings(int nodeOrdinal) {

View File

@ -52,16 +52,6 @@ public class WatchAckTests extends AbstractWatcherIntegrationTestCase {
private String id = randomAlphaOfLength(10);
@Override
protected boolean timeWarped() {
return true;
}
@Override
protected boolean enableSecurity() {
return false;
}
@Before
public void indexTestDocument() {
IndexResponse eventIndexResponse = client().prepareIndex("events", "event", id)

View File

@ -56,12 +56,7 @@ public class WatchMetadataTests extends AbstractWatcherIntegrationTestCase {
.metadata(metadata))
.get();
if (timeWarped()) {
timeWarp().trigger("_name");
} else {
// Wait for a no action entry to be added. (the condition search request will not match, because there are no docs in my-index)
assertWatchWithNoActionNeeded("_name", 1);
}
timeWarp().trigger("_name");
refresh();
SearchResponse searchResponse = client().prepareSearch(HistoryStore.INDEX_PREFIX_WITH_TEMPLATE + "*")

View File

@ -1,82 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.watcher.test.integration;
import org.apache.http.Header;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.Response;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.transport.Netty4Plugin;
import org.elasticsearch.xpack.monitoring.test.MonitoringIntegTestCase;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.junit.After;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.BASIC_AUTH_HEADER;
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.Matchers.is;
public class WatcherSettingsFilterTests extends AbstractWatcherIntegrationTestCase {
private CloseableHttpClient httpClient = HttpClients.createDefault();
@After
public void cleanup() throws IOException {
httpClient.close();
}
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put(NetworkModule.HTTP_ENABLED.getKey(), true)
.put("xpack.notification.email.account._email.smtp.host", "host.domain")
.put("xpack.notification.email.account._email.smtp.port", 587)
.put("xpack.notification.email.account._email.smtp.user", "_user")
.put("xpack.notification.email.account._email.smtp.password", "_passwd")
.build();
}
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
ArrayList<Class<? extends Plugin>> plugins = new ArrayList<>(super.nodePlugins());
plugins.add(Netty4Plugin.class); // for http
return plugins;
}
public void testGetSettingsSmtpPassword() throws Exception {
Header[] headers;
if (securityEnabled()) {
headers = new Header[] {
new BasicHeader(BASIC_AUTH_HEADER,
basicAuthHeaderValue(MonitoringIntegTestCase.SecuritySettings.TEST_USERNAME,
new SecureString(MonitoringIntegTestCase.SecuritySettings.TEST_PASSWORD.toCharArray())))};
} else {
headers = new Header[0];
}
Response response = getRestClient().performRequest("GET", "/_nodes/settings", headers);
Map<String, Object> responseMap = createParser(JsonXContent.jsonXContent, response.getEntity().getContent()).map();
Map<String, Object> nodes = (Map<String, Object>) responseMap.get("nodes");
for (Object node : nodes.values()) {
Map<String, Object> settings = (Map<String, Object>) ((Map<String, Object>) node).get("settings");
assertThat(XContentMapValues.extractValue("xpack.notification.email.account._email.smtp.user", settings),
is((Object) "_user"));
assertThat(XContentMapValues.extractValue("xpack.notification.email.account._email.smtp.password", settings),
nullValue());
}
}
}

View File

@ -54,16 +54,6 @@ import static org.hamcrest.Matchers.is;
@TestLogging("org.elasticsearch.xpack.watcher:DEBUG,org.elasticsearch.xpack.watcher.WatcherIndexingListener:TRACE")
public class TransformIntegrationTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean timeWarped() {
return true;
}
@Override
protected boolean enableSecurity() {
return false;
}
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
List<Class<? extends Plugin>> types = super.pluginTypes();
@ -146,11 +136,9 @@ public class TransformIntegrationTests extends AbstractWatcherIntegrationTestCas
.get();
assertThat(putWatchResponse.isCreated(), is(true));
if (timeWarped()) {
timeWarp().trigger("_id1");
timeWarp().trigger("_id2");
refresh();
}
timeWarp().trigger("_id1");
timeWarp().trigger("_id2");
refresh();
assertWatchWithMinimumPerformedActionsCount("_id1", 1, false);
assertWatchWithMinimumPerformedActionsCount("_id2", 1, false);
@ -195,11 +183,9 @@ public class TransformIntegrationTests extends AbstractWatcherIntegrationTestCas
).get();
assertThat(putWatchResponse.isCreated(), is(true));
if (timeWarped()) {
timeWarp().trigger("_id1");
timeWarp().trigger("_id2");
refresh();
}
timeWarp().trigger("_id1");
timeWarp().trigger("_id2");
refresh();
assertWatchWithMinimumPerformedActionsCount("_id1", 1, false);
assertWatchWithMinimumPerformedActionsCount("_id2", 1, false);
@ -241,11 +227,9 @@ public class TransformIntegrationTests extends AbstractWatcherIntegrationTestCas
.get();
assertThat(putWatchResponse.isCreated(), is(true));
if (timeWarped()) {
timeWarp().trigger("_id1");
timeWarp().trigger("_id2");
refresh();
}
timeWarp().trigger("_id1");
timeWarp().trigger("_id2");
refresh();
assertWatchWithMinimumPerformedActionsCount("_id1", 1, false);
assertWatchWithMinimumPerformedActionsCount("_id2", 1, false);

View File

@ -47,11 +47,6 @@ public class ActivateWatchTests extends AbstractWatcherIntegrationTestCase {
return false;
}
@Override
protected boolean enableSecurity() {
return false;
}
// FIXME not to be sleep based
public void testDeactivateAndActivate() throws Exception {
PutWatchResponse putWatchResponse = watcherClient().preparePutWatch()

View File

@ -16,7 +16,6 @@ import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.ack.AckWatchRequestBuilder;
import org.elasticsearch.xpack.watcher.transport.actions.ack.AckWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.get.GetWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
import org.elasticsearch.xpack.watcher.watch.WatchStatus;
@ -26,7 +25,6 @@ import static org.elasticsearch.xpack.watcher.input.InputBuilders.simpleInput;
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.cron;
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.interval;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
@ -111,15 +109,7 @@ public class ExecuteWatchTests extends AbstractWatcherIntegrationTestCase {
// but forcing will ignore the throttling
// lets wait for the watch to be ackable
if (timeWarped()) {
timeWarp().trigger("_id");
} else {
assertBusy(() -> {
GetWatchResponse getWatchResponse = watcherClient.prepareGetWatch("_id").get();
assertThat(getWatchResponse.getStatus().actionStatus("log").ackStatus().state(),
equalTo(ActionStatus.AckStatus.State.ACKABLE));
});
}
timeWarp().trigger("_id");
String[] actionIds = randomFrom(
new String[] { "_all" },

View File

@ -24,11 +24,6 @@ import static org.hamcrest.Matchers.notNullValue;
public class WatchStatusIntegrationTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean timeWarped() {
return true;
}
public void testThatStatusGetsUpdated() throws Exception {
WatcherClient watcherClient = watcherClient();
watcherClient.preparePutWatch("_name")

View File

@ -1,167 +0,0 @@
cluster:admin/repository/delete
cluster:admin/repository/get
cluster:admin/repository/put
cluster:admin/repository/verify
cluster:admin/reroute
cluster:admin/settings/update
cluster:admin/snapshot/create
cluster:admin/snapshot/delete
cluster:admin/snapshot/get
cluster:admin/snapshot/restore
cluster:admin/snapshot/status
cluster:admin/tasks/cancel
cluster:monitor/allocation/explain
cluster:monitor/health
cluster:monitor/main
cluster:monitor/nodes/hot_threads
cluster:monitor/nodes/info
cluster:monitor/nodes/stats
cluster:monitor/nodes/usage
cluster:monitor/remote/info
cluster:monitor/state
cluster:monitor/stats
cluster:monitor/task
cluster:monitor/task/get
cluster:monitor/tasks/lists
indices:admin/aliases
indices:admin/aliases/exists
indices:admin/aliases/get
indices:admin/analyze
indices:admin/cache/clear
indices:admin/close
indices:admin/create
indices:admin/delete
indices:admin/get
indices:admin/exists
indices:admin/flush
indices:admin/synced_flush
indices:admin/forcemerge
indices:admin/mapping/put
indices:admin/mappings/fields/get
indices:admin/mappings/get
indices:admin/open
indices:admin/refresh
indices:admin/settings/update
indices:admin/shards/search_shards
indices:admin/shrink
indices:admin/resize
indices:admin/rollover
indices:admin/template/delete
indices:admin/template/get
indices:admin/template/put
indices:admin/types/exists
indices:admin/upgrade
indices:admin/validate/query
indices:monitor/recovery
indices:monitor/segments
indices:monitor/settings/get
indices:monitor/shard_stores
indices:monitor/stats
indices:monitor/upgrade
indices:data/read/explain
indices:data/read/field_caps
indices:data/read/get
indices:data/read/xpack/graph/explore
indices:data/read/mget
indices:data/read/msearch
indices:data/read/mtv
cluster:admin/script/get
indices:data/read/scroll
indices:data/read/scroll/clear
indices:data/read/search
indices:data/read/tv
indices:data/write/bulk
indices:data/write/delete
indices:data/write/index
cluster:admin/script/delete
cluster:admin/script/put
indices:data/write/update
indices:data/read/sql
indices:data/read/sql/indices
indices:data/read/sql/translate
cluster:monitor/xpack/info
cluster:monitor/xpack/usage
cluster:monitor/xpack/license/get
cluster:admin/xpack/license/delete
cluster:admin/xpack/license/put
cluster:admin/xpack/monitoring/bulk
cluster:admin/xpack/security/realm/cache/clear
cluster:admin/xpack/security/roles/cache/clear
cluster:admin/xpack/security/user/authenticate
cluster:admin/xpack/security/user/change_password
cluster:admin/xpack/security/user/put
cluster:admin/xpack/security/user/delete
cluster:admin/xpack/security/user/get
cluster:admin/xpack/security/user/set_enabled
cluster:admin/xpack/security/user/has_privileges
cluster:admin/xpack/security/role/put
cluster:admin/xpack/security/role/delete
cluster:admin/xpack/security/role/get
cluster:admin/xpack/security/role_mapping/put
cluster:admin/xpack/security/role_mapping/delete
cluster:admin/xpack/security/role_mapping/get
cluster:admin/xpack/security/token/create
cluster:admin/xpack/security/token/invalidate
cluster:admin/xpack/watcher/service
cluster:admin/xpack/watcher/watch/delete
cluster:admin/xpack/watcher/watch/execute
cluster:admin/xpack/watcher/watch/put
cluster:admin/xpack/watcher/watch/ack
cluster:admin/xpack/watcher/watch/activate
cluster:monitor/xpack/watcher/watch/get
cluster:monitor/xpack/watcher/stats/dist
internal:indices/admin/upgrade
cluster:admin/ingest/pipeline/delete
cluster:admin/ingest/pipeline/get
cluster:admin/ingest/pipeline/put
cluster:admin/ingest/pipeline/simulate
cluster:admin/xpack/ml/filters/get
cluster:monitor/xpack/ml/job/results/categories/get
cluster:monitor/xpack/ml/job/stats/get
cluster:monitor/xpack/ml/job/results/buckets/get
cluster:monitor/xpack/ml/job/results/overall_buckets/get
cluster:monitor/xpack/ml/job/model_snapshots/get
cluster:monitor/xpack/ml/job/results/records/get
cluster:monitor/xpack/ml/job/results/influencers/get
cluster:internal/xpack/ml/datafeed/isolate
cluster:admin/xpack/ml/datafeeds/preview
cluster:admin/xpack/ml/datafeeds/put
cluster:admin/xpack/ml/datafeeds/update
cluster:admin/xpack/ml/job/model_snapshots/delete
cluster:admin/xpack/ml/job/validate/detector
cluster:admin/xpack/ml/job/validate
cluster:admin/xpack/ml/job/delete
cluster:admin/xpack/ml/job/model_snapshots/revert
cluster:admin/xpack/ml/datafeeds/delete
cluster:admin/xpack/ml/job/data/post
cluster:admin/xpack/ml/job/close
cluster:internal/xpack/ml/job/kill/process
cluster:admin/xpack/ml/filters/put
cluster:admin/xpack/ml/job/put
cluster:monitor/xpack/ml/job/get
cluster:monitor/xpack/ml/datafeeds/get
cluster:admin/xpack/ml/job/model_snapshots/update
cluster:admin/xpack/ml/job/flush
cluster:admin/xpack/ml/filters/delete
cluster:monitor/xpack/ml/datafeeds/stats/get
cluster:admin/xpack/ml/datafeed/stop
cluster:admin/xpack/ml/datafeed/start
cluster:admin/xpack/ml/job/open
cluster:admin/xpack/ml/job/update
cluster:internal/xpack/ml/job/update/process
cluster:admin/xpack/ml/delete_expired_data
cluster:admin/persistent/start
cluster:admin/persistent/completion
cluster:admin/persistent/update_status
cluster:admin/persistent/remove
cluster:internal/xpack/ml/job/finalize_job_execution
cluster:admin/xpack/upgrade/info
cluster:admin/xpack/upgrade
cluster:admin/reindex/rethrottle
indices:data/write/update/byquery
indices:data/write/delete/byquery
indices:data/write/reindex
cluster:admin/xpack/deprecation/info
cluster:admin/xpack/ml/job/forecast
cluster:admin/xpack/license/start_trial
cluster:admin/xpack/license/trial_status

View File

@ -1,141 +0,0 @@
cluster:admin/snapshot/status[nodes]
cluster:admin/snapshot/status[nodes][n]
cluster:admin/tasks/cancel[n]
cluster:monitor/allocation/explain
cluster:monitor/main
cluster:monitor/nodes/hot_threads[n]
cluster:monitor/nodes/info[n]
cluster:monitor/nodes/liveness
cluster:monitor/nodes/stats[n]
cluster:monitor/nodes/usage[n]
cluster:monitor/stats[n]
cluster:monitor/tasks/lists[n]
cluster:admin/xpack/security/realm/cache/clear
cluster:admin/xpack/security/realm/cache/clear[n]
cluster:admin/xpack/security/roles/cache/clear
cluster:admin/xpack/security/roles/cache/clear[n]
cluster:admin/xpack/security/role/put
cluster:admin/xpack/security/role/delete
cluster:admin/xpack/security/role/get
cluster:admin/xpack/security/user/authenticate
cluster:admin/xpack/security/user/change_password
cluster:admin/xpack/security/user/put
cluster:admin/xpack/security/user/delete
cluster:admin/xpack/security/user/get
cluster:admin/xpack/security/user/set_enabled
cluster:admin/xpack/security/token/create
cluster:admin/xpack/security/token/invalidate
indices:admin/analyze[s]
indices:admin/cache/clear[n]
indices:admin/forcemerge[n]
indices:admin/flush[s]
indices:admin/flush[s][p]
indices:admin/flush[s][r]
indices:admin/synced_flush
indices:admin/mappings/fields/get[index]
indices:admin/mappings/fields/get[index][s]
indices:admin/refresh[s]
indices:admin/refresh[s][p]
indices:admin/refresh[s][r]
indices:admin/seq_no/global_checkpoint_sync
indices:admin/seq_no/global_checkpoint_sync[p]
indices:admin/seq_no/global_checkpoint_sync[r]
indices:admin/upgrade
indices:admin/upgrade[n]
indices:admin/validate/query[s]
indices:data/read/explain[s]
indices:data/read/field_caps[index]
indices:data/read/field_caps[index][s]
indices:data/read/get[s]
indices:data/read/xpack/graph/explore
indices:data/read/mget[shard][s]
indices:data/read/mtv[shard][s]
indices:data/read/search[clear_scroll_contexts]
indices:data/read/search[free_context/scroll]
indices:data/read/search[free_context]
indices:data/read/search[phase/dfs]
indices:data/read/search[phase/fetch/id/scroll]
indices:data/read/search[phase/fetch/id]
indices:data/read/search[phase/query+fetch/scroll]
indices:data/read/search[phase/query/id]
indices:data/read/search[phase/query/scroll]
indices:data/read/search[phase/query]
indices:data/read/search[can_match]
internal:transport/proxy/indices:data/read/search[clear_scroll_contexts]
internal:transport/proxy/indices:data/read/search[free_context/scroll]
internal:transport/proxy/indices:data/read/search[free_context]
internal:transport/proxy/indices:data/read/search[phase/dfs]
internal:transport/proxy/indices:data/read/search[phase/fetch/id/scroll]
internal:transport/proxy/indices:data/read/search[phase/fetch/id]
internal:transport/proxy/indices:data/read/search[phase/query+fetch/scroll]
internal:transport/proxy/indices:data/read/search[phase/query/id]
internal:transport/proxy/indices:data/read/search[phase/query/scroll]
internal:transport/proxy/indices:data/read/search[phase/query]
internal:transport/proxy/indices:data/read/search[can_match]
indices:data/read/tv[s]
indices:data/write/bulk[s]
indices:data/write/bulk[s][p]
indices:data/write/bulk[s][r]
indices:data/write/delete
indices:data/write/delete[p]
indices:data/write/delete[r]
indices:data/write/index
indices:data/write/index[p]
indices:data/write/index[r]
indices:data/write/update[s]
indices:monitor/recovery[n]
indices:monitor/segments[n]
indices:monitor/shard_stores
indices:monitor/stats[n]
indices:monitor/upgrade[n]
indices:monitor/upgrade
indices:data/read/sql
indices:data/read/sql/indices
indices:data/read/sql/translate
internal:admin/tasks/ban
internal:cluster/node/mapping/refresh
internal:cluster/nodes/indices/shard/store
internal:cluster/nodes/indices/shard/store[n]
internal:cluster/shard/failure
internal:cluster/shard/started
internal:cluster/snapshot/update_snapshot_status
internal:discovery/zen/fd/master_ping
internal:discovery/zen/fd/ping
internal:discovery/zen/join
internal:discovery/zen/join/validate
internal:discovery/zen/leave
internal:discovery/zen/publish/send
internal:discovery/zen/publish/commit
internal:discovery/zen/rejoin
internal:discovery/zen/unicast
internal:gateway/local/allocate_dangled
internal:gateway/local/meta_state
internal:gateway/local/meta_state[n]
internal:gateway/local/started_shards
internal:gateway/local/started_shards[n]
internal:index/seq_no/resync
internal:index/seq_no/resync[p]
internal:index/seq_no/resync[r]
internal:index/shard/exists
internal:index/shard/recovery/clean_files
internal:index/shard/recovery/file_chunk
internal:index/shard/recovery/filesInfo
internal:index/shard/recovery/finalize
internal:index/shard/recovery/prepare_translog
internal:index/shard/recovery/wait_clusterstate
internal:index/shard/recovery/start_recovery
internal:index/shard/recovery/translog_ops
internal:index/shard/recovery/translog_ops
internal:index/shard/recovery/handoff_primary_context
internal:indices/admin/upgrade
internal:indices/flush/synced/in_flight
internal:indices/flush/synced/pre
internal:indices/flush/synced/sync
internal:admin/repository/verify
internal:transport/handshake
cluster:admin/reindex/rethrottle[n]
cluster:admin/xpack/upgrade
indices:data/write/update/byquery
indices:data/write/delete/byquery
indices:data/write/reindex
cluster:admin/xpack/deprecation/info

View File

@ -12,10 +12,15 @@
}
},
"params": {
"end": {
"type": "string",
"duration": {
"type": "time",
"required": false,
"description": "The end time of the forecast"
"description": "The duration of the forecast"
},
"expires_in": {
"type": "time",
"required": false,
"description": "The time interval after which the forecast expires. Expired forecasts will be deleted at the first opportunity."
}
}
},

View File

@ -15,27 +15,38 @@ setup:
---
"Test forecast unknown job":
- do:
catch: missing
xpack.ml.forecast:
job_id: "non-existing-job"
- do:
catch: missing
xpack.ml.forecast:
job_id: "non-existing-job"
---
"Test forecast on closed job":
- do:
catch: /status_exception/
xpack.ml.forecast:
job_id: "forecast-job"
- do:
catch: /status_exception/
xpack.ml.forecast:
job_id: "forecast-job"
---
"Test bad end param errors":
"Test forecast given duration is zero":
- do:
catch: /\[duration\] must be positive[:] \[0s\]/
xpack.ml.forecast:
job_id: "forecast-job"
duration: "0s"
- do:
xpack.ml.open_job:
job_id: "forecast-job"
---
"Test forecast given duration is negative":
- do:
catch: /\[duration\] must be positive[:] \[-1\]/
xpack.ml.forecast:
job_id: "forecast-job"
duration: "-1s"
- do:
catch: /parse_exception/
xpack.ml.forecast:
job_id: "forecast-job"
end: "tomorrow"
---
"Test forecast given expires_in is negative":
- do:
catch: /\[expires_in\] must be non-negative[:] \[-1\]/
xpack.ml.forecast:
job_id: "forecast-job"
expires_in: "-1s"

View File

@ -177,6 +177,7 @@ public class FullClusterRestartIT extends ESRestTestCase {
}
@SuppressWarnings("unchecked")
@AwaitsFix(bugUrl = "https://github.com/elastic/x-pack-elasticsearch/issues/3068")
public void testMonitoring() throws Exception {
waitForYellow(".monitoring-es-*");

View File

@ -23,6 +23,11 @@ integTestCluster {
setting 'xpack.monitoring.enabled', 'false'
setting 'xpack.ml.enabled', 'false'
setting 'logger.level', 'DEBUG'
// settings to test settings filtering on
setting 'xpack.notification.email.account._email.smtp.host', 'host.domain'
setting 'xpack.notification.email.account._email.smtp.port', '587'
setting 'xpack.notification.email.account._email.smtp.user', '_user'
setting 'xpack.notification.email.account._email.smtp.password', '_passwd'
plugin ':x-pack-elasticsearch:plugin'
extraConfigFile 'x-pack/roles.yml', 'roles.yml'
setupCommand 'setupTestAdminUser',

View File

@ -0,0 +1,13 @@
---
"Test watcher settings filter is applied":
- do:
cluster.state: {}
- set: { master_node: master }
- do:
nodes.info:
metric: settings
- is_true: nodes.$master.settings.xpack.notification.email.account._email.smtp.host
- is_true: nodes.$master.settings.xpack.notification.email.account._email.smtp.port
- is_true: nodes.$master.settings.xpack.notification.email.account._email.smtp.user
- is_false: nodes.$master.settings.xpack.notification.email.account._email.smtp.password

View File

@ -12,7 +12,6 @@ dependencies {
// all of x-pack for now, and transport client will be going away in the future.
compile "org.elasticsearch.plugin:x-pack-api:${version}"
compile "org.elasticsearch.client:transport:${version}"
compile "org.elasticsearch:x-pack-client-api-objects:${version}"
testCompile "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${versions.randomizedrunner}"
testCompile "junit:junit:${versions.junit}"
testCompile "org.hamcrest:hamcrest-all:${versions.hamcrest}"
@ -20,10 +19,6 @@ dependencies {
dependencyLicenses.enabled = false
dependencyLicenses {
ignoreSha 'x-pack-client-api-objects'
}
forbiddenApisTest {
// we don't use the core test-framework, no lucene classes present so we don't want the es-test-signatures to
// be pulled in