mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-02 17:09:18 +00:00
Merge branch 'master' into clock_init_without_guice
Original commit: elastic/x-pack-elasticsearch@8a1e4758c9
This commit is contained in:
commit
f13764dbc0
@ -37,7 +37,7 @@ public class IndexAuditIT extends ESIntegTestCase {
|
||||
private static final String PASS = "changeme";
|
||||
|
||||
public void testShieldIndexAuditTrailWorking() throws Exception {
|
||||
try (Response response = getRestClient().performRequest("GET", "/", Collections.emptyMap(), null,
|
||||
try (Response response = getRestClient().performRequest("GET", "/",
|
||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||
UsernamePasswordToken.basicAuthHeaderValue(USER, new SecuredString(PASS.toCharArray()))))) {
|
||||
assertThat(response.getStatusLine().getStatusCode(), is(200));
|
||||
|
@ -47,7 +47,7 @@ public class CustomRealmIT extends ESIntegTestCase {
|
||||
|
||||
public void testHttpConnectionWithNoAuthentication() throws Exception {
|
||||
try {
|
||||
getRestClient().performRequest("GET", "/", Collections.emptyMap(), null);
|
||||
getRestClient().performRequest("GET", "/");
|
||||
fail("request should have failed");
|
||||
} catch(ResponseException e) {
|
||||
Response response = e.getResponse();
|
||||
@ -58,7 +58,7 @@ public class CustomRealmIT extends ESIntegTestCase {
|
||||
}
|
||||
|
||||
public void testHttpAuthentication() throws Exception {
|
||||
try (Response response = getRestClient().performRequest("GET", "/", Collections.emptyMap(), null,
|
||||
try (Response response = getRestClient().performRequest("GET", "/",
|
||||
new BasicHeader(CustomRealm.USER_HEADER, CustomRealm.KNOWN_USER),
|
||||
new BasicHeader(CustomRealm.PW_HEADER, CustomRealm.KNOWN_PW))) {
|
||||
assertThat(response.getStatusLine().getStatusCode(), is(200));
|
||||
|
@ -18,7 +18,7 @@ subprojects {
|
||||
cluster {
|
||||
systemProperty 'es.logger.level', 'TRACE'
|
||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
||||
setting 'xpack.monitoring.agent.interval', '3s'
|
||||
setting 'xpack.monitoring.collection.interval', '3s'
|
||||
extraConfigFile 'x-pack/roles.yml', '../roles.yml'
|
||||
setupCommand 'setupTestAdminUser',
|
||||
'bin/x-pack/users', 'useradd', 'test_admin', '-p', 'changeme', '-r', 'superuser'
|
||||
|
@ -153,13 +153,13 @@ project.rootProject.subprojects.findAll { it.path.startsWith(':plugins:') }.each
|
||||
|
||||
integTest {
|
||||
cluster {
|
||||
setting 'xpack.monitoring.agent.interval', '3s'
|
||||
setting 'xpack.monitoring.agent.exporters._http.type', 'http'
|
||||
setting 'xpack.monitoring.agent.exporters._http.enabled', 'false'
|
||||
setting 'xpack.monitoring.agent.exporters._http.ssl.truststore.path', clientKeyStore.name
|
||||
setting 'xpack.monitoring.agent.exporters._http.ssl.truststore.password', 'keypass'
|
||||
setting 'xpack.monitoring.agent.exporters._http.auth.username', 'monitoring_agent'
|
||||
setting 'xpack.monitoring.agent.exporters._http.auth.password', 'changeme'
|
||||
setting 'xpack.monitoring.collection.interval', '3s'
|
||||
setting 'xpack.monitoring.collection.exporters._http.type', 'http'
|
||||
setting 'xpack.monitoring.collection.exporters._http.enabled', 'false'
|
||||
setting 'xpack.monitoring.collection.exporters._http.ssl.truststore.path', clientKeyStore.name
|
||||
setting 'xpack.monitoring.collection.exporters._http.ssl.truststore.password', 'keypass'
|
||||
setting 'xpack.monitoring.collection.exporters._http.auth.username', 'monitoring_agent'
|
||||
setting 'xpack.monitoring.collection.exporters._http.auth.password', 'changeme'
|
||||
|
||||
setting 'xpack.security.transport.ssl.enabled', 'true'
|
||||
setting 'xpack.security.http.ssl.enabled', 'true'
|
||||
|
@ -73,8 +73,8 @@ public class SmokeTestMonitoringWithSecurityIT extends ESIntegTestCase {
|
||||
URI uri = new URI("https", null, httpAddress.getHostString(), httpAddress.getPort(), "/", null, null);
|
||||
|
||||
Settings exporterSettings = Settings.builder()
|
||||
.put("xpack.monitoring.agent.exporters._http.enabled", true)
|
||||
.put("xpack.monitoring.agent.exporters._http.host", uri.toString())
|
||||
.put("xpack.monitoring.collection.exporters._http.enabled", true)
|
||||
.put("xpack.monitoring.collection.exporters._http.host", uri.toString())
|
||||
.build();
|
||||
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(exporterSettings));
|
||||
}
|
||||
@ -82,8 +82,8 @@ public class SmokeTestMonitoringWithSecurityIT extends ESIntegTestCase {
|
||||
@After
|
||||
public void disableExporter() {
|
||||
Settings exporterSettings = Settings.builder()
|
||||
.putNull("xpack.monitoring.agent.exporters._http.enabled")
|
||||
.putNull("xpack.monitoring.agent.exporters._http.host")
|
||||
.putNull("xpack.monitoring.collection.exporters._http.enabled")
|
||||
.putNull("xpack.monitoring.collection.exporters._http.host")
|
||||
.build();
|
||||
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(exporterSettings));
|
||||
}
|
||||
|
@ -11,9 +11,9 @@
|
||||
metric: [ settings ]
|
||||
|
||||
- is_true: nodes
|
||||
- is_true: nodes.$master.settings.xpack.monitoring.agent.exporters._http.type
|
||||
- is_true: nodes.$master.settings.xpack.monitoring.collection.exporters._http.type
|
||||
|
||||
- is_false: nodes.$master.settings.xpack.monitoring.agent.exporters._http.auth.username
|
||||
- is_false: nodes.$master.settings.xpack.monitoring.agent.exporters._http.auth.password
|
||||
- is_false: nodes.$master.settings.xpack.monitoring.agent.exporters._http.ssl.truststore.path
|
||||
- is_false: nodes.$master.settings.xpack.monitoring.agent.exporters._http.ssl.truststore.password
|
||||
- is_false: nodes.$master.settings.xpack.monitoring.collection.exporters._http.auth.username
|
||||
- is_false: nodes.$master.settings.xpack.monitoring.collection.exporters._http.auth.password
|
||||
- is_false: nodes.$master.settings.xpack.monitoring.collection.exporters._http.ssl.truststore.path
|
||||
- is_false: nodes.$master.settings.xpack.monitoring.collection.exporters._http.ssl.truststore.password
|
||||
|
@ -133,7 +133,7 @@ integTest {
|
||||
// TODO: fix this rest test to not depend on a hardcoded port!
|
||||
systemProperty 'tests.rest.blacklist', 'getting_started/10_monitor_cluster_health/*,bulk/10_basic/*'
|
||||
cluster {
|
||||
setting 'xpack.monitoring.agent.interval', '3s'
|
||||
setting 'xpack.monitoring.collection.interval', '3s'
|
||||
waitCondition = { NodeInfo node, AntBuilder ant ->
|
||||
File tmpFile = new File(node.cwd, 'wait.success')
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"graph.explore": {
|
||||
"xpack.graph.explore": {
|
||||
"documentation": "https://www.elastic.co/guide/en/graph/current/explore.html",
|
||||
"methods": ["GET", "POST"],
|
||||
"url": {
|
||||
"path": "/{index}/_xpack/graph/_explore",
|
||||
"paths": ["/{index}/_xpack/graph/_explore", "/{index}/{type}/_xpack/graph/_explore"],
|
||||
"paths": ["/{index}/_xpack/graph/_explore", "/{index}/{type}/_xpack/graph/_explore"],
|
||||
"parts" : {
|
||||
"index": {
|
||||
"type" : "list",
|
||||
@ -23,7 +23,7 @@
|
||||
"timeout": {
|
||||
"type" : "time",
|
||||
"description" : "Explicit operation timeout"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"body": {
|
@ -1,19 +1,21 @@
|
||||
---
|
||||
setup:
|
||||
- do:
|
||||
indices.create:
|
||||
index: test_1
|
||||
body:
|
||||
settings:
|
||||
index:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
mappings:
|
||||
test:
|
||||
properties:
|
||||
keys:
|
||||
type : integer
|
||||
|
||||
---
|
||||
"Test basic graph explore":
|
||||
- do:
|
||||
indices.create:
|
||||
index: test_1
|
||||
body:
|
||||
settings:
|
||||
index:
|
||||
number_of_replicas: 0
|
||||
number_of_shards: 1
|
||||
mappings:
|
||||
test:
|
||||
properties:
|
||||
keys:
|
||||
type : "integer"
|
||||
|
||||
- do:
|
||||
index:
|
||||
index: test_1
|
||||
@ -37,7 +39,7 @@
|
||||
wait_for_status: green
|
||||
|
||||
- do:
|
||||
graph.explore:
|
||||
xpack.graph.explore:
|
||||
index: test_1
|
||||
type: test
|
||||
body: {"query": {"match": {"keys": 1}},"controls":{"use_significance":false},"vertices":[{"field": "keys","min_doc_count": 1}]}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"license.delete": {
|
||||
"xpack.license.delete": {
|
||||
"documentation": "https://www.elastic.co/guide/en/shield/current/license-management.html",
|
||||
"methods": ["DELETE"],
|
||||
"url": {
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"license.get": {
|
||||
"xpack.license.get": {
|
||||
"documentation": "https://www.elastic.co/guide/en/shield/current/license-management.html",
|
||||
"methods": ["GET"],
|
||||
"url": {
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"license.post": {
|
||||
"xpack.license.post": {
|
||||
"documentation": "https://www.elastic.co/guide/en/shield/current/license-management.html",
|
||||
"methods": ["PUT", "POST"],
|
||||
"url": {
|
@ -3,70 +3,76 @@
|
||||
|
||||
## current license version
|
||||
- do:
|
||||
license.post:
|
||||
acknowledge: true
|
||||
body: |
|
||||
{"license":{"uid":"893361dc-9749-4997-93cb-802e3d7fa4a8","type":"basic","issue_date_in_millis":1411948800000,"expiry_date_in_millis":1914278399999,"max_nodes":1,"issued_to":"issuedTo","issuer":"issuer","signature":"AAAAAgAAAA0lKPZ0a7aZquUltho/AAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxakxZdW5IMlhlTHNoN1N2MXMvRFk4d3JTZEx3R3RRZ0pzU3lobWJKZnQvSEFva0ppTHBkWkprZWZSQi9iNmRQNkw1SlpLN0lDalZCS095MXRGN1lIZlpYcVVTTnFrcTE2dzhJZmZrdFQrN3JQeGwxb0U0MXZ0dDJHSERiZTVLOHNzSDByWnpoZEphZHBEZjUrTVBxRENNSXNsWWJjZllaODdzVmEzUjNiWktNWGM5TUhQV2plaUo4Q1JOUml4MXNuL0pSOEhQaVB2azhmUk9QVzhFeTFoM1Q0RnJXSG53MWk2K055c28zSmRnVkF1b2JSQkFLV2VXUmVHNDZ2R3o2VE1qbVNQS2lxOHN5bUErZlNIWkZSVmZIWEtaSU9wTTJENDVvT1NCYklacUYyK2FwRW9xa0t6dldMbmMzSGtQc3FWOTgzZ3ZUcXMvQkt2RUZwMFJnZzlvL2d2bDRWUzh6UG5pdENGWFRreXNKNkE9PQAAAQAALuQ44S3IG6SzolcXVJ6Z4CIXORDrYQ+wdLCeey0XdujTslAOj+k+vNgo6wauc7Uswi01esHu4lb5IgpvKy7RRCbh5bj/z2ubu2qMJqopp9BQyD7VQjVfqmG6seUMJwJ1a5Avvm9r41YPSPcrii3bKK2e1l6jK6N8ibCvnTyY/XkYGCJrBWTSJePDbg6ErbyodrZ37x1StLbPWcNAkmweyHjDJnvYnbeZZO7A3NmubXZjW7Ttf8/YwQyE00PqMcl7fVPY3hkKpAeHf8aaJbqkKYbqZuER3EWJX7ZvLVb1dNdNg8aXRn7YrkQcYwWgptYQpfV+D7yEJ4j5muAEoler"}}
|
||||
xpack.license.post:
|
||||
acknowledge: true
|
||||
body: |
|
||||
{"license":{"uid":"893361dc-9749-4997-93cb-802e3d7fa4a8","type":"basic","issue_date_in_millis":1411948800000,"expiry_date_in_millis":1914278399999,"max_nodes":1,"issued_to":"issuedTo","issuer":"issuer","signature":"AAAAAgAAAA0lKPZ0a7aZquUltho/AAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxakxZdW5IMlhlTHNoN1N2MXMvRFk4d3JTZEx3R3RRZ0pzU3lobWJKZnQvSEFva0ppTHBkWkprZWZSQi9iNmRQNkw1SlpLN0lDalZCS095MXRGN1lIZlpYcVVTTnFrcTE2dzhJZmZrdFQrN3JQeGwxb0U0MXZ0dDJHSERiZTVLOHNzSDByWnpoZEphZHBEZjUrTVBxRENNSXNsWWJjZllaODdzVmEzUjNiWktNWGM5TUhQV2plaUo4Q1JOUml4MXNuL0pSOEhQaVB2azhmUk9QVzhFeTFoM1Q0RnJXSG53MWk2K055c28zSmRnVkF1b2JSQkFLV2VXUmVHNDZ2R3o2VE1qbVNQS2lxOHN5bUErZlNIWkZSVmZIWEtaSU9wTTJENDVvT1NCYklacUYyK2FwRW9xa0t6dldMbmMzSGtQc3FWOTgzZ3ZUcXMvQkt2RUZwMFJnZzlvL2d2bDRWUzh6UG5pdENGWFRreXNKNkE9PQAAAQAALuQ44S3IG6SzolcXVJ6Z4CIXORDrYQ+wdLCeey0XdujTslAOj+k+vNgo6wauc7Uswi01esHu4lb5IgpvKy7RRCbh5bj/z2ubu2qMJqopp9BQyD7VQjVfqmG6seUMJwJ1a5Avvm9r41YPSPcrii3bKK2e1l6jK6N8ibCvnTyY/XkYGCJrBWTSJePDbg6ErbyodrZ37x1StLbPWcNAkmweyHjDJnvYnbeZZO7A3NmubXZjW7Ttf8/YwQyE00PqMcl7fVPY3hkKpAeHf8aaJbqkKYbqZuER3EWJX7ZvLVb1dNdNg8aXRn7YrkQcYwWgptYQpfV+D7yEJ4j5muAEoler"}}
|
||||
|
||||
- match: { license_status: "valid" }
|
||||
|
||||
- do:
|
||||
license.get: {}
|
||||
xpack.license.get: {}
|
||||
|
||||
## a license object has 10 attributes
|
||||
- length: { license: 10 }
|
||||
|
||||
## bwc for licenses format
|
||||
- do:
|
||||
license.post:
|
||||
acknowledge: true
|
||||
body: |
|
||||
{"licenses":[{"uid":"893361dc-9749-4997-93cb-802e3d7fa4a8","type":"basic","issue_date_in_millis":1411948800000,"expiry_date_in_millis":1914278399999,"max_nodes":1,"issued_to":"issuedTo","issuer":"issuer","signature":"AAAAAgAAAA0lKPZ0a7aZquUltho/AAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxakxZdW5IMlhlTHNoN1N2MXMvRFk4d3JTZEx3R3RRZ0pzU3lobWJKZnQvSEFva0ppTHBkWkprZWZSQi9iNmRQNkw1SlpLN0lDalZCS095MXRGN1lIZlpYcVVTTnFrcTE2dzhJZmZrdFQrN3JQeGwxb0U0MXZ0dDJHSERiZTVLOHNzSDByWnpoZEphZHBEZjUrTVBxRENNSXNsWWJjZllaODdzVmEzUjNiWktNWGM5TUhQV2plaUo4Q1JOUml4MXNuL0pSOEhQaVB2azhmUk9QVzhFeTFoM1Q0RnJXSG53MWk2K055c28zSmRnVkF1b2JSQkFLV2VXUmVHNDZ2R3o2VE1qbVNQS2lxOHN5bUErZlNIWkZSVmZIWEtaSU9wTTJENDVvT1NCYklacUYyK2FwRW9xa0t6dldMbmMzSGtQc3FWOTgzZ3ZUcXMvQkt2RUZwMFJnZzlvL2d2bDRWUzh6UG5pdENGWFRreXNKNkE9PQAAAQAALuQ44S3IG6SzolcXVJ6Z4CIXORDrYQ+wdLCeey0XdujTslAOj+k+vNgo6wauc7Uswi01esHu4lb5IgpvKy7RRCbh5bj/z2ubu2qMJqopp9BQyD7VQjVfqmG6seUMJwJ1a5Avvm9r41YPSPcrii3bKK2e1l6jK6N8ibCvnTyY/XkYGCJrBWTSJePDbg6ErbyodrZ37x1StLbPWcNAkmweyHjDJnvYnbeZZO7A3NmubXZjW7Ttf8/YwQyE00PqMcl7fVPY3hkKpAeHf8aaJbqkKYbqZuER3EWJX7ZvLVb1dNdNg8aXRn7YrkQcYwWgptYQpfV+D7yEJ4j5muAEoler"}]}
|
||||
xpack.license.post:
|
||||
acknowledge: true
|
||||
body: |
|
||||
{"licenses":[{"uid":"893361dc-9749-4997-93cb-802e3d7fa4a8","type":"basic","issue_date_in_millis":1411948800000,"expiry_date_in_millis":1914278399999,"max_nodes":1,"issued_to":"issuedTo","issuer":"issuer","signature":"AAAAAgAAAA0lKPZ0a7aZquUltho/AAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxakxZdW5IMlhlTHNoN1N2MXMvRFk4d3JTZEx3R3RRZ0pzU3lobWJKZnQvSEFva0ppTHBkWkprZWZSQi9iNmRQNkw1SlpLN0lDalZCS095MXRGN1lIZlpYcVVTTnFrcTE2dzhJZmZrdFQrN3JQeGwxb0U0MXZ0dDJHSERiZTVLOHNzSDByWnpoZEphZHBEZjUrTVBxRENNSXNsWWJjZllaODdzVmEzUjNiWktNWGM5TUhQV2plaUo4Q1JOUml4MXNuL0pSOEhQaVB2azhmUk9QVzhFeTFoM1Q0RnJXSG53MWk2K055c28zSmRnVkF1b2JSQkFLV2VXUmVHNDZ2R3o2VE1qbVNQS2lxOHN5bUErZlNIWkZSVmZIWEtaSU9wTTJENDVvT1NCYklacUYyK2FwRW9xa0t6dldMbmMzSGtQc3FWOTgzZ3ZUcXMvQkt2RUZwMFJnZzlvL2d2bDRWUzh6UG5pdENGWFRreXNKNkE9PQAAAQAALuQ44S3IG6SzolcXVJ6Z4CIXORDrYQ+wdLCeey0XdujTslAOj+k+vNgo6wauc7Uswi01esHu4lb5IgpvKy7RRCbh5bj/z2ubu2qMJqopp9BQyD7VQjVfqmG6seUMJwJ1a5Avvm9r41YPSPcrii3bKK2e1l6jK6N8ibCvnTyY/XkYGCJrBWTSJePDbg6ErbyodrZ37x1StLbPWcNAkmweyHjDJnvYnbeZZO7A3NmubXZjW7Ttf8/YwQyE00PqMcl7fVPY3hkKpAeHf8aaJbqkKYbqZuER3EWJX7ZvLVb1dNdNg8aXRn7YrkQcYwWgptYQpfV+D7yEJ4j5muAEoler"}]}
|
||||
|
||||
- match: { license_status: "valid" }
|
||||
|
||||
- do:
|
||||
license.get: {}
|
||||
xpack.license.get: {}
|
||||
|
||||
- length: { license: 10 }
|
||||
|
||||
## license version: 1.x
|
||||
- do:
|
||||
license.post:
|
||||
acknowledge: true
|
||||
body: |
|
||||
{"licenses":[{"uid":"893361dc-9749-4997-93cb-802e3d7fa4a8","type":"subscription","subscription_type":"gold","issue_date_in_millis":1411948800000,"feature":"shield","expiry_date_in_millis":1914278399999,"max_nodes":1,"issued_to":"issuedTo","issuer":"issuer","signature":"AAAAAQAAAA0LVAywwpSH94cyXr4zAAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxakxZdW5IMlhlTHNoN1N2MXMvRFk4d3JTZEx3R3RRZ0pzU3lobWJKZnQvSEFva0ppTHBkWkprZWZSQi9iNmRQNkw1SlpLN0lDalZCS095MXRGN1lIZlpYcVVTTnFrcTE2dzhJZmZrdFQrN3JQeGwxb0U0MXZ0dDJHSERiZTVLOHNzSDByWnpoZEphZHBEZjUrTVBxRENNSXNsWWJjZllaODdzVmEzUjNiWktNWGM5TUhQV2plaUo4Q1JOUml4MXNuL0pSOEhQaVB2azhmUk9QVzhFeTFoM1Q0RnJXSG53MWk2K055c28zSmRnVkF1b2JSQkFLV2VXUmVHNDZ2R3o2VE1qbVNQS2lxOHN5bUErZlNIWkZSVmZIWEtaSU9wTTJENDVvT1NCYklacUYyK2FwRW9xa0t6dldMbmMzSGtQc3FWOTgzZ3ZUcXMvQkt2RUZwMFJnZzlvL2d2bDRWUzh6UG5pdENGWFRreXNKNkE9PQAAAQA4qscc/URRZVdFoLwgy9dqybYEQLW8YLkiAyPV5XHHHdtk+dtZIepiNEDkUXhSX2waVJlsNRF8/4kqplDfwNoD2TUM8fTgiIfiSiZYGDTGST+yW/5eAveEU5J5v1liBN27bwkqL+V4YAa0Tcm7NKKwjScWKAHiTU3vF8chPkGfCHE0kQgVwPC9RE82pTw0s6/uR4PfLGNFfqPM0uiE5nucfVrtj89JQiO/KA/7ZyFbo7VTNXxZQt7T7rZWBCP9KIjptXzcWuk08Q5S+rSoJNYbFo3HGKtrCVsRz/55rceNtdwKKXu1IwnSeir4I1/KLduQTtFLy0+1th87VS8T88UT"}]}
|
||||
xpack.license.post:
|
||||
acknowledge: true
|
||||
body: |
|
||||
{"licenses":[{"uid":"893361dc-9749-4997-93cb-802e3d7fa4a8","type":"subscription","subscription_type":"gold","issue_date_in_millis":1411948800000,"feature":"shield","expiry_date_in_millis":1914278399999,"max_nodes":1,"issued_to":"issuedTo","issuer":"issuer","signature":"AAAAAQAAAA0LVAywwpSH94cyXr4zAAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxakxZdW5IMlhlTHNoN1N2MXMvRFk4d3JTZEx3R3RRZ0pzU3lobWJKZnQvSEFva0ppTHBkWkprZWZSQi9iNmRQNkw1SlpLN0lDalZCS095MXRGN1lIZlpYcVVTTnFrcTE2dzhJZmZrdFQrN3JQeGwxb0U0MXZ0dDJHSERiZTVLOHNzSDByWnpoZEphZHBEZjUrTVBxRENNSXNsWWJjZllaODdzVmEzUjNiWktNWGM5TUhQV2plaUo4Q1JOUml4MXNuL0pSOEhQaVB2azhmUk9QVzhFeTFoM1Q0RnJXSG53MWk2K055c28zSmRnVkF1b2JSQkFLV2VXUmVHNDZ2R3o2VE1qbVNQS2lxOHN5bUErZlNIWkZSVmZIWEtaSU9wTTJENDVvT1NCYklacUYyK2FwRW9xa0t6dldMbmMzSGtQc3FWOTgzZ3ZUcXMvQkt2RUZwMFJnZzlvL2d2bDRWUzh6UG5pdENGWFRreXNKNkE9PQAAAQA4qscc/URRZVdFoLwgy9dqybYEQLW8YLkiAyPV5XHHHdtk+dtZIepiNEDkUXhSX2waVJlsNRF8/4kqplDfwNoD2TUM8fTgiIfiSiZYGDTGST+yW/5eAveEU5J5v1liBN27bwkqL+V4YAa0Tcm7NKKwjScWKAHiTU3vF8chPkGfCHE0kQgVwPC9RE82pTw0s6/uR4PfLGNFfqPM0uiE5nucfVrtj89JQiO/KA/7ZyFbo7VTNXxZQt7T7rZWBCP9KIjptXzcWuk08Q5S+rSoJNYbFo3HGKtrCVsRz/55rceNtdwKKXu1IwnSeir4I1/KLduQTtFLy0+1th87VS8T88UT"}]}
|
||||
|
||||
- match: { license_status: "valid" }
|
||||
|
||||
- do:
|
||||
license.get: {}
|
||||
xpack.license.get: {}
|
||||
|
||||
- length: { license: 10 }
|
||||
|
||||
## multiple licenses version: 1.x
|
||||
- do:
|
||||
license.post:
|
||||
acknowledge: true
|
||||
body: |
|
||||
{"licenses":[{"uid":"893361dc-9749-4997-93cb-802e3d7fa4a8","type":"internal","subscription_type":"none","issue_date_in_millis":1411948800000,"feature":"shield","expiry_date_in_millis":1440892799999,"max_nodes":1,"issued_to":"issuedTo","issuer":"issuer","signature":"AAAAAQAAAA04Q4ky3rFyyWLFkytEAAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxakxZdW5IMlhlTHNoN1N2MXMvRFk4d3JTZEx3R3RRZ0pzU3lobWJKZnQvSEFva0ppTHBkWkprZWZSQi9iNmRQNkw1SlpLN0lDalZCS095MXRGN1lIZlpYcVVTTnFrcTE2dzhJZmZrdFQrN3JQeGwxb0U0MXZ0dDJHSERiZTVLOHNzSDByWnpoZEphZHBEZjUrTVBxRENNSXNsWWJjZllaODdzVmEzUjNiWktNWGM5TUhQV2plaUo4Q1JOUml4MXNuL0pSOEhQaVB2azhmUk9QVzhFeTFoM1Q0RnJXSG53MWk2K055c28zSmRnVkF1b2JSQkFLV2VXUmVHNDZ2R3o2VE1qbVNQS2lxOHN5bUErZlNIWkZSVmZIWEtaSU9wTTJENDVvT1NCYklacUYyK2FwRW9xa0t6dldMbmMzSGtQc3FWOTgzZ3ZUcXMvQkt2RUZwMFJnZzlvL2d2bDRWUzh6UG5pdENGWFRreXNKNkE9PQAAAQBxMvUMn4h2E4R4TQMijahTxQj4LPQO4f1M79UxX/XkDlGcH+J5pRHx08OtTRPsFL1lED+h+PIXx307Vo+PNDsOxrWvoYZeYBkOLAO3ny9vhQga+52jYhMxIuFrT9xbcSCSNpMhGojgOIPU2WgiopVdVcimo1+Gk8VtklPB1wPwFzfOjOnPgp/Icx3WYpfkeAUUOyWUYiFIBAe4bnz84iF+xwLKbgYk6aHF25ECBtdb/Uruhcm9+jEFpoIEUtCouvvk9C+NJZ4OickV4xpRgaRG2x9PONH8ZN0QGhGYhJGbisoCxuDmlLsyVxqxfMu3n/r7/jdsEJScjAlSrsLDOu6H"},{"uid":"893361dc-9749-4997-93cb-802e3dofh7aa","type":"internal","subscription_type":"none","issue_date_in_millis":1443484800000,"feature":"watcher","expiry_date_in_millis":1914278399999,"max_nodes":1,"issued_to":"issuedTo","issuer":"issuer","signature":"AAAAAQAAAA0Sc90guRIaQEmgLvMnAAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxakxZdW5IMlhlTHNoN1N2MXMvRFk4d3JTZEx3R3RRZ0pzU3lobWJKZnQvSEFva0ppTHBkWkprZWZSQi9iNmRQNkw1SlpLN0lDalZCS095MXRGN1lIZlpYcVVTTnFrcTE2dzhJZmZrdFQrN3JQeGwxb0U0MXZ0dDJHSERiZTVLOHNzSDByWnpoZEphZHBEZjUrTVBxRENNSXNsWWJjZllaODdzVmEzUjNiWktNWGM5TUhQV2plaUo4Q1JOUml4MXNuL0pSOEhQaVB2azhmUk9QVzhFeTFoM1Q0RnJXSG53MWk2K055c28zSmRnVkF1b2JSQkFLV2VXUmVHNDZ2R3o2VE1qbVNQS2lxOHN5bUErZlNIWkZSVmZIWEtaSU9wTTJENDVvT1NCYklacUYyK2FwRW9xa0t6dldMbmMzSGtQc3FWOTgzZ3ZUcXMvQkt2RUZwMFJnZzlvL2d2bDRWUzh6UG5pdENGWFRreXNKNkE9PQAAAQCQ94dju0pnDZR3Uuypi0ic3aQJ+nvVqe+U8u79Dga5n1qIjcHDh7HvIBJEkF+tnVPlo/PXV/x7BZSwVY1PVErit+6rYix1yuHEgqwxmx/VdRICjCaZM6tk0Ob4dZCPv6Ebn2Mmk89KHC/PwiLPqF6QfwV/Pkpa8k2A3ORJmvYSDvXhe6tCs8dqc4ebrsFxqrZjwWh5CZSpzqqZBFXlngDv2N0hHhpGlueRszD0JJ5dfEL5ZA1DDOrgO9OJVejSHyRqe1L5QRUNdXPVfS+EAG0Dd1cNdJ/sMpYCPnVjbw6iq2/YgM3cuztsXVBY7ij4WnoP3ce7Zjs9TwHn+IqzftC6"}]}
|
||||
xpack.license.post:
|
||||
acknowledge: true
|
||||
body: |
|
||||
{"licenses":[{"uid":"893361dc-9749-4997-93cb-802e3d7fa4a8","type":"internal","subscription_type":"none","issue_date_in_millis":1411948800000,"feature":"shield","expiry_date_in_millis":1440892799999,"max_nodes":1,"issued_to":"issuedTo","issuer":"issuer","signature":"AAAAAQAAAA04Q4ky3rFyyWLFkytEAAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxakxZdW5IMlhlTHNoN1N2MXMvRFk4d3JTZEx3R3RRZ0pzU3lobWJKZnQvSEFva0ppTHBkWkprZWZSQi9iNmRQNkw1SlpLN0lDalZCS095MXRGN1lIZlpYcVVTTnFrcTE2dzhJZmZrdFQrN3JQeGwxb0U0MXZ0dDJHSERiZTVLOHNzSDByWnpoZEphZHBEZjUrTVBxRENNSXNsWWJjZllaODdzVmEzUjNiWktNWGM5TUhQV2plaUo4Q1JOUml4MXNuL0pSOEhQaVB2azhmUk9QVzhFeTFoM1Q0RnJXSG53MWk2K055c28zSmRnVkF1b2JSQkFLV2VXUmVHNDZ2R3o2VE1qbVNQS2lxOHN5bUErZlNIWkZSVmZIWEtaSU9wTTJENDVvT1NCYklacUYyK2FwRW9xa0t6dldMbmMzSGtQc3FWOTgzZ3ZUcXMvQkt2RUZwMFJnZzlvL2d2bDRWUzh6UG5pdENGWFRreXNKNkE9PQAAAQBxMvUMn4h2E4R4TQMijahTxQj4LPQO4f1M79UxX/XkDlGcH+J5pRHx08OtTRPsFL1lED+h+PIXx307Vo+PNDsOxrWvoYZeYBkOLAO3ny9vhQga+52jYhMxIuFrT9xbcSCSNpMhGojgOIPU2WgiopVdVcimo1+Gk8VtklPB1wPwFzfOjOnPgp/Icx3WYpfkeAUUOyWUYiFIBAe4bnz84iF+xwLKbgYk6aHF25ECBtdb/Uruhcm9+jEFpoIEUtCouvvk9C+NJZ4OickV4xpRgaRG2x9PONH8ZN0QGhGYhJGbisoCxuDmlLsyVxqxfMu3n/r7/jdsEJScjAlSrsLDOu6H"},{"uid":"893361dc-9749-4997-93cb-802e3dofh7aa","type":"internal","subscription_type":"none","issue_date_in_millis":1443484800000,"feature":"watcher","expiry_date_in_millis":1914278399999,"max_nodes":1,"issued_to":"issuedTo","issuer":"issuer","signature":"AAAAAQAAAA0Sc90guRIaQEmgLvMnAAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxakxZdW5IMlhlTHNoN1N2MXMvRFk4d3JTZEx3R3RRZ0pzU3lobWJKZnQvSEFva0ppTHBkWkprZWZSQi9iNmRQNkw1SlpLN0lDalZCS095MXRGN1lIZlpYcVVTTnFrcTE2dzhJZmZrdFQrN3JQeGwxb0U0MXZ0dDJHSERiZTVLOHNzSDByWnpoZEphZHBEZjUrTVBxRENNSXNsWWJjZllaODdzVmEzUjNiWktNWGM5TUhQV2plaUo4Q1JOUml4MXNuL0pSOEhQaVB2azhmUk9QVzhFeTFoM1Q0RnJXSG53MWk2K055c28zSmRnVkF1b2JSQkFLV2VXUmVHNDZ2R3o2VE1qbVNQS2lxOHN5bUErZlNIWkZSVmZIWEtaSU9wTTJENDVvT1NCYklacUYyK2FwRW9xa0t6dldMbmMzSGtQc3FWOTgzZ3ZUcXMvQkt2RUZwMFJnZzlvL2d2bDRWUzh6UG5pdENGWFRreXNKNkE9PQAAAQCQ94dju0pnDZR3Uuypi0ic3aQJ+nvVqe+U8u79Dga5n1qIjcHDh7HvIBJEkF+tnVPlo/PXV/x7BZSwVY1PVErit+6rYix1yuHEgqwxmx/VdRICjCaZM6tk0Ob4dZCPv6Ebn2Mmk89KHC/PwiLPqF6QfwV/Pkpa8k2A3ORJmvYSDvXhe6tCs8dqc4ebrsFxqrZjwWh5CZSpzqqZBFXlngDv2N0hHhpGlueRszD0JJ5dfEL5ZA1DDOrgO9OJVejSHyRqe1L5QRUNdXPVfS+EAG0Dd1cNdJ/sMpYCPnVjbw6iq2/YgM3cuztsXVBY7ij4WnoP3ce7Zjs9TwHn+IqzftC6"}]}
|
||||
|
||||
- match: { license_status: "valid" }
|
||||
|
||||
- do:
|
||||
license.get: {}
|
||||
xpack.license.get: {}
|
||||
|
||||
- length: { license: 10 }
|
||||
- match: { license.uid: "893361dc-9749-4997-93cb-802e3dofh7aa" }
|
||||
|
||||
---
|
||||
"Should throw 404 after license deletion":
|
||||
- do:
|
||||
xpack.license.post:
|
||||
acknowledge: true
|
||||
body: |
|
||||
{"licenses":[{"uid":"894371dc-9t49-4997-93cb-8o2e3r7fa6a8","type":"trial","issue_date_in_millis":1411948800000,"expiry_date_in_millis":1916956799999,"max_nodes":1,"issued_to":"issuedTo","issuer":"issuer","signature":"AAAAAgAAAA0FWh0T9njItjQ2qammAAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxakxZdW5IMlhlTHNoN1N2MXMvRFk4d3JTZEx3R3RRZ0pzU3lobWJKZnQvSEFva0ppTHBkWkprZWZSQi9iNmRQNkw1SlpLN0lDalZCS095MXRGN1lIZlpYcVVTTnFrcTE2dzhJZmZrdFQrN3JQeGwxb0U0MXZ0dDJHSERiZTVLOHNzSDByWnpoZEphZHBEZjUrTVBxRENNSXNsWWJjZllaODdzVmEzUjNiWktNWGM5TUhQV2plaUo4Q1JOUml4MXNuL0pSOEhQaVB2azhmUk9QVzhFeTFoM1Q0RnJXSG53MWk2K055c28zSmRnVkF1b2JSQkFLV2VXUmVHNDZ2R3o2VE1qbVNQS2lxOHN5bUErZlNIWkZSVmZIWEtaSU9wTTJENDVvT1NCYklacUYyK2FwRW9xa0t6dldMbmMzSGtQc3FWOTgzZ3ZUcXMvQkt2RUZwMFJnZzlvL2d2bDRWUzh6UG5pdENGWFRreXNKNkE9PQAAAQBZhvozA0trrxhUZ1QbaTsKTna9C5KVQ6pv8yg1pnsBpZXCl8kX1SrgoFn1bXq61IvJwfw5qnmYNiH3hRhTO9EyaCBqaLk8NXZQ6TrRkQSpEnnBwAYUkZeKXsIuBoOk4B4mzwC/r8aMAkzrTiEBtBbog+57cSaU9y37Gkdd+1jXCQrxP+jOEUf7gnXWZvE6oeRroLvCt1fYn09k0CF8kKTbrPTSjC6igZR3uvTHyee74XQ9PRavvHax73T4UOEdQZX/P1ibSQIWKbBRD5YQ1POYVjTayoltTnWLMxfEcAkkATJZLhpBEHST7kZWjrTS6J1dCReJc7a8Vsj/78HXvOIy"}]}
|
||||
|
||||
|
||||
- do:
|
||||
license.delete: {}
|
||||
xpack.license.delete: {}
|
||||
|
||||
- match: { acknowledged: true }
|
||||
|
||||
- do:
|
||||
catch: missing
|
||||
license.get: {}
|
||||
catch: missing
|
||||
|
@ -52,55 +52,55 @@ public class MonitoringSettings extends AbstractComponent {
|
||||
* Sampling interval between two collections (default to 10s)
|
||||
*/
|
||||
public static final Setting<TimeValue> INTERVAL =
|
||||
timeSetting(key("agent.interval"), TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope);
|
||||
timeSetting(collectionKey("interval"), TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope);
|
||||
|
||||
/**
|
||||
* Timeout value when collecting index statistics (default to 10m)
|
||||
*/
|
||||
public static final Setting<TimeValue> INDEX_STATS_TIMEOUT =
|
||||
timeSetting(key("agent.index.stats.timeout"), TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope);
|
||||
timeSetting(collectionKey("index.stats.timeout"), TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope);
|
||||
|
||||
/**
|
||||
* Timeout value when collecting total indices statistics (default to 10m)
|
||||
*/
|
||||
public static final Setting<TimeValue> INDICES_STATS_TIMEOUT =
|
||||
timeSetting(key("agent.indices.stats.timeout"), TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope);
|
||||
timeSetting(collectionKey("indices.stats.timeout"), TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope);
|
||||
|
||||
/**
|
||||
* List of indices names whose stats will be exported (default to all indices)
|
||||
*/
|
||||
public static final Setting<List<String>> INDICES =
|
||||
listSetting(key("agent.indices"), Collections.emptyList(), Function.identity(), Property.Dynamic, Property.NodeScope);
|
||||
listSetting(collectionKey("indices"), Collections.emptyList(), Function.identity(), Property.Dynamic, Property.NodeScope);
|
||||
|
||||
/**
|
||||
* Timeout value when collecting the cluster state (default to 10m)
|
||||
*/
|
||||
public static final Setting<TimeValue> CLUSTER_STATE_TIMEOUT =
|
||||
timeSetting(key("agent.cluster.state.timeout"), TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope);
|
||||
timeSetting(collectionKey("cluster.state.timeout"), TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope);
|
||||
|
||||
/**
|
||||
* Timeout value when collecting the recovery information (default to 10m)
|
||||
*/
|
||||
public static final Setting<TimeValue> CLUSTER_STATS_TIMEOUT =
|
||||
timeSetting(key("agent.cluster.stats.timeout"), TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope);
|
||||
timeSetting(collectionKey("cluster.stats.timeout"), TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope);
|
||||
|
||||
/**
|
||||
* Timeout value when collecting the recovery information (default to 10m)
|
||||
*/
|
||||
public static final Setting<TimeValue> INDEX_RECOVERY_TIMEOUT =
|
||||
timeSetting(key("agent.index.recovery.timeout"), TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope);
|
||||
timeSetting(collectionKey("index.recovery.timeout"), TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope);
|
||||
|
||||
/**
|
||||
* Flag to indicate if only active recoveries should be collected (default to false: all recoveries are collected)
|
||||
*/
|
||||
public static final Setting<Boolean> INDEX_RECOVERY_ACTIVE_ONLY =
|
||||
boolSetting(key("agent.index.recovery.active_only"), false, Property.Dynamic, Property.NodeScope) ;
|
||||
boolSetting(collectionKey("index.recovery.active_only"), false, Property.Dynamic, Property.NodeScope) ;
|
||||
|
||||
/**
|
||||
* List of collectors allowed to collect data (default to all)
|
||||
*/
|
||||
public static final Setting<List<String>> COLLECTORS =
|
||||
listSetting(key("agent.collectors"), Collections.emptyList(), Function.identity(), Property.NodeScope);
|
||||
listSetting(collectionKey("collectors"), Collections.emptyList(), Function.identity(), Property.NodeScope);
|
||||
|
||||
/**
|
||||
* The default retention duration of the monitoring history data.
|
||||
@ -123,7 +123,7 @@ public class MonitoringSettings extends AbstractComponent {
|
||||
* Settings/Options per configured exporter
|
||||
*/
|
||||
public static final Setting<Settings> EXPORTERS_SETTINGS =
|
||||
groupSetting(key("agent.exporters."), Property.Dynamic, Property.NodeScope);
|
||||
groupSetting(collectionKey("exporters."), Property.Dynamic, Property.NodeScope);
|
||||
|
||||
public static List<Setting<?>> getSettings() {
|
||||
return Arrays.asList(INDICES,
|
||||
@ -141,7 +141,7 @@ public class MonitoringSettings extends AbstractComponent {
|
||||
}
|
||||
|
||||
public static List<String> getSettingsFilter() {
|
||||
return Arrays.asList("xpack.monitoring.agent.exporters.*.auth.*", "xpack.monitoring.agent.exporters.*.ssl.*");
|
||||
return Arrays.asList("xpack.monitoring.collection.exporters.*.auth.*", "xpack.monitoring.collection.exporters.*.ssl.*");
|
||||
}
|
||||
|
||||
|
||||
@ -227,6 +227,17 @@ public class MonitoringSettings extends AbstractComponent {
|
||||
this.indices = indices.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix the {@code key} with the Monitoring prefix and "collection." .
|
||||
*
|
||||
* @param key The key to prefix
|
||||
* @return The key prefixed by the product prefixes + "collection." .
|
||||
* @see #key(String)
|
||||
*/
|
||||
static String collectionKey(String key) {
|
||||
return key("collection." + key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix the {@code key} with the Monitoring prefix.
|
||||
*
|
||||
|
@ -536,11 +536,8 @@ public class HttpExporter extends Exporter {
|
||||
for (String host : hosts) {
|
||||
try {
|
||||
HttpExporterUtils.parseHostWithPath(host, "");
|
||||
} catch (URISyntaxException e) {
|
||||
throw new SettingsException("[xpack.monitoring.agent.exporter] invalid host: [" + host + "]." +
|
||||
" error: [" + e.getMessage() + "]");
|
||||
} catch (MalformedURLException e) {
|
||||
throw new SettingsException("[xpack.monitoring.agent.exporter] invalid host: [" + host + "]." +
|
||||
} catch (URISyntaxException | MalformedURLException e) {
|
||||
throw new SettingsException("[xpack.monitoring.collection.exporters] invalid host: [" + host + "]." +
|
||||
" error: [" + e.getMessage() + "]");
|
||||
}
|
||||
}
|
||||
|
@ -32,9 +32,9 @@ public class MonitoringF {
|
||||
settings.put("script.inline", "true");
|
||||
settings.put("security.manager.enabled", "false");
|
||||
settings.put("cluster.name", MonitoringF.class.getSimpleName());
|
||||
settings.put("xpack.monitoring.agent.interval", "5s");
|
||||
settings.put("xpack.monitoring.collection.interval", "1s");
|
||||
if (!CollectionUtils.isEmpty(args)) {
|
||||
settings.putArray("xpack.monitoring.agent.collectors", args);
|
||||
settings.putArray("xpack.monitoring.collection.collectors", args);
|
||||
}
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
@ -32,7 +32,7 @@ public abstract class AbstractExporterTemplateTestCase extends MonitoringIntegTe
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1");
|
||||
|
||||
for (Map.Entry<String, String> setting : exporterSettings().getAsMap().entrySet()) {
|
||||
settings.put("xpack.monitoring.agent.exporters._exporter." + setting.getKey(), setting.getValue());
|
||||
settings.put("xpack.monitoring.collection.exporters._exporter." + setting.getKey(), setting.getValue());
|
||||
}
|
||||
return settings.build();
|
||||
}
|
||||
|
@ -176,8 +176,8 @@ public class ExportersTests extends ESTestCase {
|
||||
final AtomicReference<Settings> settingsHolder = new AtomicReference<>();
|
||||
|
||||
Settings nodeSettings = Settings.builder()
|
||||
.put("xpack.monitoring.agent.exporters._name0.type", "_type")
|
||||
.put("xpack.monitoring.agent.exporters._name1.type", "_type")
|
||||
.put("xpack.monitoring.collection.exporters._name0.type", "_type")
|
||||
.put("xpack.monitoring.collection.exporters._name1.type", "_type")
|
||||
.build();
|
||||
clusterSettings = new ClusterSettings(nodeSettings, new HashSet<>(Arrays.asList(MonitoringSettings.EXPORTERS_SETTINGS)));
|
||||
|
||||
@ -197,8 +197,8 @@ public class ExportersTests extends ESTestCase {
|
||||
assertThat(settings, hasEntry("_name1.type", "_type"));
|
||||
|
||||
Settings update = Settings.builder()
|
||||
.put("xpack.monitoring.agent.exporters._name0.foo", "bar")
|
||||
.put("xpack.monitoring.agent.exporters._name1.foo", "bar")
|
||||
.put("xpack.monitoring.collection.exporters._name0.foo", "bar")
|
||||
.put("xpack.monitoring.collection.exporters._name1.foo", "bar")
|
||||
.build();
|
||||
clusterSettings.applySettings(update);
|
||||
assertThat(settingsHolder.get(), notNullValue());
|
||||
@ -216,8 +216,8 @@ public class ExportersTests extends ESTestCase {
|
||||
factories.put("mock", factory);
|
||||
factories.put("mock_master_only", masterOnlyFactory);
|
||||
Exporters exporters = new Exporters(Settings.builder()
|
||||
.put("xpack.monitoring.agent.exporters._name0.type", "mock")
|
||||
.put("xpack.monitoring.agent.exporters._name1.type", "mock_master_only")
|
||||
.put("xpack.monitoring.collection.exporters._name0.type", "mock")
|
||||
.put("xpack.monitoring.collection.exporters._name1.type", "mock_master_only")
|
||||
.build(), factories, clusterService, clusterSettings);
|
||||
exporters.start();
|
||||
|
||||
@ -241,8 +241,8 @@ public class ExportersTests extends ESTestCase {
|
||||
factories.put("mock", factory);
|
||||
factories.put("mock_master_only", masterOnlyFactory);
|
||||
Exporters exporters = new Exporters(Settings.builder()
|
||||
.put("xpack.monitoring.agent.exporters._name0.type", "mock")
|
||||
.put("xpack.monitoring.agent.exporters._name1.type", "mock_master_only")
|
||||
.put("xpack.monitoring.collection.exporters._name0.type", "mock")
|
||||
.put("xpack.monitoring.collection.exporters._name1.type", "mock_master_only")
|
||||
.build(), factories, clusterService, clusterSettings);
|
||||
exporters.start();
|
||||
|
||||
@ -270,7 +270,7 @@ public class ExportersTests extends ESTestCase {
|
||||
logger.info("--> creating {} exporters", nbExporters);
|
||||
Settings.Builder settings = Settings.builder();
|
||||
for (int i = 0; i < nbExporters; i++) {
|
||||
settings.put("xpack.monitoring.agent.exporters._name" + String.valueOf(i) + ".type", "record");
|
||||
settings.put("xpack.monitoring.collection.exporters._name" + String.valueOf(i) + ".type", "record");
|
||||
}
|
||||
|
||||
Exporter.Factory factory = new CountingExportFactory("record", false);
|
||||
|
@ -95,10 +95,10 @@ public class HttpExporterTests extends MonitoringIntegTestCase {
|
||||
|
||||
Settings.Builder builder = Settings.builder()
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put("xpack.monitoring.agent.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.agent.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort())
|
||||
.put("xpack.monitoring.agent.exporters._http.connection.keep_alive", false)
|
||||
.put("xpack.monitoring.agent.exporters._http.update_mappings", false);
|
||||
.put("xpack.monitoring.collection.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.collection.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort())
|
||||
.put("xpack.monitoring.collection.exporters._http.connection.keep_alive", false)
|
||||
.put("xpack.monitoring.collection.exporters._http.update_mappings", false);
|
||||
|
||||
internalCluster().startNode(builder);
|
||||
|
||||
@ -133,23 +133,23 @@ public class HttpExporterTests extends MonitoringIntegTestCase {
|
||||
// disable exporting to be able to use non valid hosts
|
||||
Settings.Builder builder = Settings.builder()
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put("xpack.monitoring.agent.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.agent.exporters._http.host", "test0");
|
||||
.put("xpack.monitoring.collection.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.collection.exporters._http.host", "test0");
|
||||
|
||||
String nodeName = internalCluster().startNode(builder);
|
||||
|
||||
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder()
|
||||
.putArray("xpack.monitoring.agent.exporters._http.host", "test1")));
|
||||
.putArray("xpack.monitoring.collection.exporters._http.host", "test1")));
|
||||
assertThat(getExporter(nodeName).hosts, Matchers.arrayContaining("test1"));
|
||||
|
||||
// wipes the non array settings
|
||||
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder()
|
||||
.putArray("xpack.monitoring.agent.exporters._http.host", "test2")
|
||||
.put("xpack.monitoring.agent.exporters._http.host", "")));
|
||||
.putArray("xpack.monitoring.collection.exporters._http.host", "test2")
|
||||
.put("xpack.monitoring.collection.exporters._http.host", "")));
|
||||
assertThat(getExporter(nodeName).hosts, Matchers.arrayContaining("test2"));
|
||||
|
||||
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder()
|
||||
.putArray("xpack.monitoring.agent.exporters._http.host", "test3")));
|
||||
.putArray("xpack.monitoring.collection.exporters._http.host", "test3")));
|
||||
assertThat(getExporter(nodeName).hosts, Matchers.arrayContaining("test3"));
|
||||
}
|
||||
|
||||
@ -157,10 +157,10 @@ public class HttpExporterTests extends MonitoringIntegTestCase {
|
||||
|
||||
Settings.Builder builder = Settings.builder()
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put("xpack.monitoring.agent.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.agent.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort())
|
||||
.put("xpack.monitoring.agent.exporters._http.connection.keep_alive", false)
|
||||
.put("xpack.monitoring.agent.exporters._http.update_mappings", false);
|
||||
.put("xpack.monitoring.collection.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.collection.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort())
|
||||
.put("xpack.monitoring.collection.exporters._http.connection.keep_alive", false)
|
||||
.put("xpack.monitoring.collection.exporters._http.update_mappings", false);
|
||||
|
||||
logger.info("--> starting node");
|
||||
|
||||
@ -221,7 +221,7 @@ public class HttpExporterTests extends MonitoringIntegTestCase {
|
||||
assertNotNull("Unable to start the second mock web server", secondWebServer);
|
||||
|
||||
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(
|
||||
Settings.builder().putArray("xpack.monitoring.agent.exporters._http.host",
|
||||
Settings.builder().putArray("xpack.monitoring.collection.exporters._http.host",
|
||||
secondWebServer.getHostName() + ":" + secondWebServer.getPort())).get());
|
||||
|
||||
// a new exporter is created on update, so we need to re-fetch it
|
||||
@ -274,9 +274,9 @@ public class HttpExporterTests extends MonitoringIntegTestCase {
|
||||
public void testUnsupportedClusterVersion() throws Exception {
|
||||
Settings.Builder builder = Settings.builder()
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put("xpack.monitoring.agent.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.agent.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort())
|
||||
.put("xpack.monitoring.agent.exporters._http.connection.keep_alive", false);
|
||||
.put("xpack.monitoring.collection.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.collection.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort())
|
||||
.put("xpack.monitoring.collection.exporters._http.connection.keep_alive", false);
|
||||
|
||||
logger.info("--> starting node");
|
||||
|
||||
@ -302,10 +302,10 @@ public class HttpExporterTests extends MonitoringIntegTestCase {
|
||||
public void testDynamicIndexFormatChange() throws Exception {
|
||||
Settings.Builder builder = Settings.builder()
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put("xpack.monitoring.agent.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.agent.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort())
|
||||
.put("xpack.monitoring.agent.exporters._http.connection.keep_alive", false)
|
||||
.put("xpack.monitoring.agent.exporters._http.update_mappings", false);
|
||||
.put("xpack.monitoring.collection.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.collection.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort())
|
||||
.put("xpack.monitoring.collection.exporters._http.connection.keep_alive", false)
|
||||
.put("xpack.monitoring.collection.exporters._http.update_mappings", false);
|
||||
|
||||
String agentNode = internalCluster().startNode(builder);
|
||||
|
||||
@ -356,7 +356,7 @@ public class HttpExporterTests extends MonitoringIntegTestCase {
|
||||
String newTimeFormat = randomFrom("YY", "YYYY", "YYYY.MM", "YYYY-MM", "MM.YYYY", "MM");
|
||||
logger.info("--> updating index time format setting to {}", newTimeFormat);
|
||||
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder()
|
||||
.put("xpack.monitoring.agent.exporters._http.index.name.time_format", newTimeFormat)));
|
||||
.put("xpack.monitoring.collection.exporters._http.index.name.time_format", newTimeFormat)));
|
||||
|
||||
|
||||
logger.info("--> exporting a second event");
|
||||
@ -402,9 +402,9 @@ public class HttpExporterTests extends MonitoringIntegTestCase {
|
||||
|
||||
Settings.Builder builder = Settings.builder()
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put("xpack.monitoring.agent.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.agent.exporters._http.host", host)
|
||||
.put("xpack.monitoring.agent.exporters._http.connection.keep_alive", false);
|
||||
.put("xpack.monitoring.collection.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.collection.exporters._http.host", host)
|
||||
.put("xpack.monitoring.collection.exporters._http.connection.keep_alive", false);
|
||||
|
||||
String agentNode = internalCluster().startNode(builder);
|
||||
HttpExporter exporter = getExporter(agentNode);
|
||||
|
@ -65,8 +65,8 @@ public class LocalExporterTests extends MonitoringIntegTestCase {
|
||||
|
||||
public void testSimpleExport() throws Exception {
|
||||
internalCluster().startNode(Settings.builder()
|
||||
.put("xpack.monitoring.agent.exporters._local.type", LocalExporter.TYPE)
|
||||
.put("xpack.monitoring.agent.exporters._local.enabled", true)
|
||||
.put("xpack.monitoring.collection.exporters._local.type", LocalExporter.TYPE)
|
||||
.put("xpack.monitoring.collection.exporters._local.enabled", true)
|
||||
.build());
|
||||
securedEnsureGreen();
|
||||
|
||||
@ -96,7 +96,7 @@ public class LocalExporterTests extends MonitoringIntegTestCase {
|
||||
|
||||
public void testTemplateCreation() throws Exception {
|
||||
internalCluster().startNode(Settings.builder()
|
||||
.put("xpack.monitoring.agent.exporters._local.type", LocalExporter.TYPE)
|
||||
.put("xpack.monitoring.collection.exporters._local.type", LocalExporter.TYPE)
|
||||
.build());
|
||||
securedEnsureGreen();
|
||||
|
||||
@ -111,8 +111,8 @@ public class LocalExporterTests extends MonitoringIntegTestCase {
|
||||
String timeFormat = randomFrom("YY", "YYYY", "YYYY.MM", "YYYY-MM", "MM.YYYY", "MM");
|
||||
|
||||
internalCluster().startNode(Settings.builder()
|
||||
.put("xpack.monitoring.agent.exporters._local.type", LocalExporter.TYPE)
|
||||
.put("xpack.monitoring.agent.exporters._local." + LocalExporter.INDEX_NAME_TIME_FORMAT_SETTING, timeFormat)
|
||||
.put("xpack.monitoring.collection.exporters._local.type", LocalExporter.TYPE)
|
||||
.put("xpack.monitoring.collection.exporters._local." + LocalExporter.INDEX_NAME_TIME_FORMAT_SETTING, timeFormat)
|
||||
.build());
|
||||
securedEnsureGreen();
|
||||
|
||||
@ -130,7 +130,7 @@ public class LocalExporterTests extends MonitoringIntegTestCase {
|
||||
|
||||
logger.debug("--> updates the timestamp");
|
||||
timeFormat = randomFrom("dd", "dd.MM.YYYY", "dd.MM");
|
||||
updateClusterSettings(Settings.builder().put("xpack.monitoring.agent.exporters._local.index.name.time_format", timeFormat));
|
||||
updateClusterSettings(Settings.builder().put("xpack.monitoring.collection.exporters._local.index.name.time_format", timeFormat));
|
||||
exporter = getLocalExporter("_local"); // we need to get it again.. as it was rebuilt
|
||||
indexName = ".monitoring-es-" + MonitoringTemplateUtils.TEMPLATE_VERSION + "-"
|
||||
+ DateTimeFormat.forPattern(timeFormat).withZoneUTC().print(doc.getTimestamp());
|
||||
@ -144,8 +144,8 @@ public class LocalExporterTests extends MonitoringIntegTestCase {
|
||||
|
||||
public void testLocalExporterFlush() throws Exception {
|
||||
internalCluster().startNode(Settings.builder()
|
||||
.put("xpack.monitoring.agent.exporters._local.type", LocalExporter.TYPE)
|
||||
.put("xpack.monitoring.agent.exporters._local.enabled", true)
|
||||
.put("xpack.monitoring.collection.exporters._local.type", LocalExporter.TYPE)
|
||||
.put("xpack.monitoring.collection.exporters._local.enabled", true)
|
||||
.build());
|
||||
securedEnsureGreen();
|
||||
|
||||
|
@ -44,7 +44,7 @@ public class ClusterStateTests extends MonitoringIntegTestCase {
|
||||
.put(super.nodeSettings(nodeOrdinal))
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put(MonitoringSettings.COLLECTORS.getKey(), ClusterStateCollector.NAME)
|
||||
.put("xpack.monitoring.agent.exporters.default_local.type", "local")
|
||||
.put("xpack.monitoring.collection.exporters.default_local.type", "local")
|
||||
.put("node.attr.custom", randomInt)
|
||||
.build();
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public class ClusterStatsTests extends MonitoringIntegTestCase {
|
||||
.put(super.nodeSettings(nodeOrdinal))
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put(MonitoringSettings.COLLECTORS.getKey(), ClusterStatsCollector.NAME)
|
||||
.put("xpack.monitoring.agent.exporters.default_local.type", "local")
|
||||
.put("xpack.monitoring.collection.exporters.default_local.type", "local")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ public class IndexRecoveryTests extends MonitoringIntegTestCase {
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put(MonitoringSettings.INDICES.getKey(), INDEX_PREFIX + "*")
|
||||
.put(MonitoringSettings.COLLECTORS.getKey(), IndexRecoveryCollector.NAME)
|
||||
.put("xpack.monitoring.agent.exporters.default_local.type", "local")
|
||||
.put("xpack.monitoring.collection.exporters.default_local.type", "local")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ public class IndexStatsTests extends MonitoringIntegTestCase {
|
||||
.put(super.nodeSettings(nodeOrdinal))
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put(MonitoringSettings.COLLECTORS.getKey(), IndexStatsCollector.NAME)
|
||||
.put("xpack.monitoring.agent.exporters.default_local.type", "local")
|
||||
.put("xpack.monitoring.collection.exporters.default_local.type", "local")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ public class IndicesStatsTests extends MonitoringIntegTestCase {
|
||||
.put(super.nodeSettings(nodeOrdinal))
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put(MonitoringSettings.COLLECTORS.getKey(), IndicesStatsCollector.NAME)
|
||||
.put("xpack.monitoring.agent.exporters.default_local.type", "local")
|
||||
.put("xpack.monitoring.collection.exporters.default_local.type", "local")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ public class MultiNodesStatsTests extends MonitoringIntegTestCase {
|
||||
return Settings.builder()
|
||||
.put(super.nodeSettings(nodeOrdinal))
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put("xpack.monitoring.agent.exporters.default_local.type", "local")
|
||||
.put("xpack.monitoring.collection.exporters.default_local.type", "local")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ public class NodeStatsTests extends MonitoringIntegTestCase {
|
||||
.put(super.nodeSettings(nodeOrdinal))
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put(MonitoringSettings.COLLECTORS.getKey(), NodeStatsCollector.NAME)
|
||||
.put("xpack.monitoring.agent.exporters.default_local.type", LocalExporter.TYPE)
|
||||
.put("xpack.monitoring.collection.exporters.default_local.type", LocalExporter.TYPE)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ public class ShardsTests extends MonitoringIntegTestCase {
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put(MonitoringSettings.COLLECTORS.getKey(), ShardsCollector.NAME)
|
||||
.put(MonitoringSettings.INDICES.getKey(), INDEX_PREFIX + "*")
|
||||
.put("xpack.monitoring.agent.exporters.default_local.type", "local")
|
||||
.put("xpack.monitoring.collection.exporters.default_local.type", "local")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ public class LocalIndicesCleanerTests extends AbstractIndicesCleanerTestCase {
|
||||
protected Settings nodeSettings(int nodeOrdinal) {
|
||||
return Settings.builder()
|
||||
.put(super.nodeSettings(nodeOrdinal))
|
||||
.put("xpack.monitoring.agent.exporters._local.type", LocalExporter.TYPE)
|
||||
.put("xpack.monitoring.collection.exporters._local.type", LocalExporter.TYPE)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,6 @@ import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||
import org.elasticsearch.xpack.monitoring.MonitoringSettings;
|
||||
import org.elasticsearch.xpack.monitoring.test.MonitoringIntegTestCase;
|
||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
@ -22,7 +21,8 @@ import java.util.Map;
|
||||
import static org.elasticsearch.common.xcontent.support.XContentMapValues.extractValue;
|
||||
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.nullValue;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
public class MonitoringSettingsFilterTests extends MonitoringIntegTestCase {
|
||||
|
||||
@ -32,13 +32,13 @@ public class MonitoringSettingsFilterTests extends MonitoringIntegTestCase {
|
||||
.put(super.nodeSettings(nodeOrdinal))
|
||||
.put(NetworkModule.HTTP_ENABLED.getKey(), true)
|
||||
.put(MonitoringSettings.INTERVAL.getKey(), "-1")
|
||||
.put("xpack.monitoring.agent.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.agent.exporters._http.enabled", false)
|
||||
.put("xpack.monitoring.agent.exporters._http.auth.username", "_user")
|
||||
.put("xpack.monitoring.agent.exporters._http.auth.password", "_passwd")
|
||||
.put("xpack.monitoring.agent.exporters._http.ssl.truststore.path", "/path/to/truststore")
|
||||
.put("xpack.monitoring.agent.exporters._http.ssl.truststore.password", "_passwd")
|
||||
.put("xpack.monitoring.agent.exporters._http.ssl.hostname_verification", true)
|
||||
.put("xpack.monitoring.collection.exporters._http.type", "http")
|
||||
.put("xpack.monitoring.collection.exporters._http.enabled", false)
|
||||
.put("xpack.monitoring.collection.exporters._http.auth.username", "_user")
|
||||
.put("xpack.monitoring.collection.exporters._http.auth.password", "_passwd")
|
||||
.put("xpack.monitoring.collection.exporters._http.ssl.truststore.path", "/path/to/truststore")
|
||||
.put("xpack.monitoring.collection.exporters._http.ssl.truststore.password", "_passwd")
|
||||
.put("xpack.monitoring.collection.exporters._http.ssl.hostname_verification", true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@ -60,13 +60,13 @@ public class MonitoringSettingsFilterTests extends MonitoringIntegTestCase {
|
||||
for (Object node : nodes.values()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> settings = (Map<String, Object>) ((Map<String, Object>) node).get("settings");
|
||||
assertThat(extractValue("xpack.monitoring.agent.exporters._http.type", settings), Matchers.<Object>equalTo("http"));
|
||||
assertThat(extractValue("xpack.monitoring.agent.exporters._http.enabled", settings), Matchers.<Object>equalTo("false"));
|
||||
assertNullSetting(settings, "xpack.monitoring.agent.exporters._http.auth.username");
|
||||
assertNullSetting(settings, "xpack.monitoring.agent.exporters._http.auth.password");
|
||||
assertNullSetting(settings, "xpack.monitoring.agent.exporters._http.ssl.truststore.path");
|
||||
assertNullSetting(settings, "xpack.monitoring.agent.exporters._http.ssl.truststore.password");
|
||||
assertNullSetting(settings, "xpack.monitoring.agent.exporters._http.ssl.hostname_verification");
|
||||
assertThat(extractValue("xpack.monitoring.collection.exporters._http.type", settings), equalTo("http"));
|
||||
assertThat(extractValue("xpack.monitoring.collection.exporters._http.enabled", settings), equalTo("false"));
|
||||
assertNullSetting(settings, "xpack.monitoring.collection.exporters._http.auth.username");
|
||||
assertNullSetting(settings, "xpack.monitoring.collection.exporters._http.auth.password");
|
||||
assertNullSetting(settings, "xpack.monitoring.collection.exporters._http.ssl.truststore.path");
|
||||
assertNullSetting(settings, "xpack.monitoring.collection.exporters._http.ssl.truststore.password");
|
||||
assertNullSetting(settings, "xpack.monitoring.collection.exporters._http.ssl.hostname_verification");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +175,6 @@ public class Security implements ActionPlugin {
|
||||
list.add(LoggingAuditTrail.class);
|
||||
}
|
||||
list.add(SecurityLicensee.class);
|
||||
list.add(InternalCryptoService.class);
|
||||
list.add(FileRolesStore.class);
|
||||
list.add(Realms.class);
|
||||
return list;
|
||||
|
@ -143,7 +143,7 @@ public class SecurityFeatureSet implements XPackFeatureSet {
|
||||
|
||||
static boolean systemKeyUsage(CryptoService cryptoService) {
|
||||
// we can piggy back on the encryption enabled method as it is only enabled if there is a system key
|
||||
return cryptoService != null && cryptoService.encryptionEnabled();
|
||||
return cryptoService != null && cryptoService.isEncryptionEnabled();
|
||||
}
|
||||
|
||||
static class Usage extends XPackFeatureSet.Usage {
|
||||
|
@ -191,7 +191,7 @@ public class SecurityActionFilter extends AbstractComponent implements ActionFil
|
||||
if (response instanceof SearchResponse) {
|
||||
SearchResponse searchResponse = (SearchResponse) response;
|
||||
String scrollId = searchResponse.getScrollId();
|
||||
if (scrollId != null && !cryptoService.signed(scrollId)) {
|
||||
if (scrollId != null && !cryptoService.isSigned(scrollId)) {
|
||||
searchResponse.scrollId(cryptoService.sign(scrollId));
|
||||
}
|
||||
return response;
|
||||
|
@ -5,7 +5,6 @@
|
||||
*/
|
||||
package org.elasticsearch.xpack.security.crypto;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@ -26,27 +25,10 @@ public interface CryptoService {
|
||||
*/
|
||||
String unsignAndVerify(String text);
|
||||
|
||||
/**
|
||||
* Signs the given text and returns the signed text (original text + signature)
|
||||
* @param text the string to sign
|
||||
* @param key the key to sign the text with
|
||||
* @param systemKey the system key. This is optional and if the key != systemKey then the format of the
|
||||
* message will change
|
||||
*/
|
||||
String sign(String text, SecretKey key, SecretKey systemKey) throws IOException;
|
||||
|
||||
/**
|
||||
* Unsigns the given signed text, verifies the original text with the attached signature and if valid returns
|
||||
* the unsigned (original) text. If signature verification fails a {@link IllegalArgumentException} is thrown.
|
||||
* @param text the string to unsign and verify
|
||||
* @param key the key to unsign the text with
|
||||
*/
|
||||
String unsignAndVerify(String text, SecretKey key);
|
||||
|
||||
/**
|
||||
* Checks whether the given text is signed.
|
||||
*/
|
||||
boolean signed(String text);
|
||||
boolean isSigned(String text);
|
||||
|
||||
/**
|
||||
* Encrypts the provided char array and returns the encrypted values in a char array
|
||||
@ -55,13 +37,6 @@ public interface CryptoService {
|
||||
*/
|
||||
char[] encrypt(char[] chars);
|
||||
|
||||
/**
|
||||
* Encrypts the provided byte array and returns the encrypted value
|
||||
* @param bytes the data to encrypt
|
||||
* @return encrypted data
|
||||
*/
|
||||
byte[] encrypt(byte[] bytes);
|
||||
|
||||
/**
|
||||
* Decrypts the provided char array and returns the plain-text chars
|
||||
* @param chars the data to decrypt
|
||||
@ -69,64 +44,16 @@ public interface CryptoService {
|
||||
*/
|
||||
char[] decrypt(char[] chars);
|
||||
|
||||
/**
|
||||
* Decrypts the provided char array and returns the plain-text chars
|
||||
* @param chars the data to decrypt
|
||||
* @param key the key to decrypt the data with
|
||||
* @return plaintext chars
|
||||
*/
|
||||
char[] decrypt(char[] chars, SecretKey key);
|
||||
|
||||
/**
|
||||
* Decrypts the provided byte array and returns the unencrypted bytes
|
||||
* @param bytes the bytes to decrypt
|
||||
* @return plaintext bytes
|
||||
*/
|
||||
byte[] decrypt(byte[] bytes);
|
||||
|
||||
/**
|
||||
* Decrypts the provided byte array and returns the unencrypted bytes
|
||||
* @param bytes the bytes to decrypt
|
||||
* @param key the key to decrypt the data with
|
||||
* @return plaintext bytes
|
||||
*/
|
||||
byte[] decrypt(byte[] bytes, SecretKey key);
|
||||
|
||||
/**
|
||||
* Checks whether the given chars are encrypted
|
||||
* @param chars the chars to check if they are encrypted
|
||||
* @return true is data is encrypted
|
||||
*/
|
||||
boolean encrypted(char[] chars);
|
||||
|
||||
/**
|
||||
* Checks whether the given bytes are encrypted
|
||||
* @param bytes the chars to check if they are encrypted
|
||||
* @return true is data is encrypted
|
||||
*/
|
||||
boolean encrypted(byte[] bytes);
|
||||
|
||||
/**
|
||||
* Registers a listener to be notified of key changes
|
||||
* @param listener the listener to be notified
|
||||
*/
|
||||
void register(Listener listener);
|
||||
boolean isEncrypted(char[] chars);
|
||||
|
||||
/**
|
||||
* Flag for callers to determine if values will actually be encrypted or returned plaintext
|
||||
* @return true if values will be encrypted
|
||||
*/
|
||||
boolean encryptionEnabled();
|
||||
|
||||
interface Listener {
|
||||
/**
|
||||
* This method will be called immediately after a new system key and encryption key are loaded by the
|
||||
* service. This provides the old keys back to the clients so that they may perform decryption and re-encryption
|
||||
* of data after a key has been changed
|
||||
*
|
||||
* @param oldSystemKey the pre-existing system key
|
||||
* @param oldEncryptionKey the pre-existing encryption key
|
||||
*/
|
||||
void onKeyChange(SecretKey oldSystemKey, SecretKey oldEncryptionKey);
|
||||
}
|
||||
boolean isEncryptionEnabled();
|
||||
}
|
||||
|
@ -5,20 +5,6 @@
|
||||
*/
|
||||
package org.elasticsearch.xpack.security.crypto;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Setting;
|
||||
import org.elasticsearch.common.settings.Setting.Property;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.watcher.FileChangesListener;
|
||||
import org.elasticsearch.watcher.FileWatcher;
|
||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||
import org.elasticsearch.xpack.XPackPlugin;
|
||||
import org.elasticsearch.xpack.security.authc.support.CharArrays;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
@ -27,7 +13,6 @@ import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -39,16 +24,25 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.component.AbstractComponent;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Setting;
|
||||
import org.elasticsearch.common.settings.Setting.Property;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.xpack.XPackPlugin;
|
||||
import org.elasticsearch.xpack.security.authc.support.CharArrays;
|
||||
|
||||
import static org.elasticsearch.xpack.security.Security.setting;
|
||||
import static org.elasticsearch.xpack.security.authc.support.SecuredString.constantTimeEquals;
|
||||
|
||||
public class InternalCryptoService extends AbstractLifecycleComponent implements CryptoService {
|
||||
public class InternalCryptoService extends AbstractComponent implements CryptoService {
|
||||
|
||||
public static final String KEY_ALGO = "HmacSHA512";
|
||||
public static final int KEY_SIZE = 1024;
|
||||
@ -73,65 +67,33 @@ public class InternalCryptoService extends AbstractLifecycleComponent implements
|
||||
public static final Setting<String> ENCRYPTION_KEY_ALGO_SETTING =
|
||||
new Setting<>(setting("encryption_key.algorithm"), DEFAULT_KEY_ALGORITH, s -> s, Property.NodeScope);
|
||||
|
||||
private final Environment env;
|
||||
private final ResourceWatcherService watcherService;
|
||||
private final List<Listener> listeners;
|
||||
private final SecureRandom secureRandom = new SecureRandom();
|
||||
private final String encryptionAlgorithm;
|
||||
private final String keyAlgorithm;
|
||||
private final int keyLength;
|
||||
private final int ivLength;
|
||||
|
||||
private Path keyFile;
|
||||
private final Path keyFile;
|
||||
|
||||
private SecretKey randomKey;
|
||||
private String randomKeyBase64;
|
||||
private final SecretKey randomKey;
|
||||
private final String randomKeyBase64;
|
||||
|
||||
private volatile SecretKey encryptionKey;
|
||||
private volatile SecretKey systemKey;
|
||||
private volatile SecretKey signingKey;
|
||||
private final SecretKey encryptionKey;
|
||||
private final SecretKey systemKey;
|
||||
private final SecretKey signingKey;
|
||||
|
||||
@Inject
|
||||
public InternalCryptoService(Settings settings, Environment env, ResourceWatcherService watcherService) {
|
||||
this(settings, env, watcherService, Collections.<Listener>emptyList());
|
||||
}
|
||||
|
||||
InternalCryptoService(Settings settings, Environment env, ResourceWatcherService watcherService, List<Listener> listeners) {
|
||||
public InternalCryptoService(Settings settings, Environment env) throws Exception {
|
||||
super(settings);
|
||||
this.env = env;
|
||||
this.watcherService = watcherService;
|
||||
this.listeners = new CopyOnWriteArrayList<>(listeners);
|
||||
this.encryptionAlgorithm = ENCRYPTION_ALGO_SETTING.get(settings);
|
||||
this.keyLength = ENCRYPTION_KEY_LENGTH_SETTING.get(settings);
|
||||
this.ivLength = keyLength / 8;
|
||||
this.keyAlgorithm = ENCRYPTION_KEY_ALGO_SETTING.get(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStart() throws ElasticsearchException {
|
||||
if (keyLength % 8 != 0) {
|
||||
throw new IllegalArgumentException("invalid key length [" + keyLength + "]. value must be a multiple of 8");
|
||||
}
|
||||
|
||||
loadKeys();
|
||||
FileWatcher watcher = new FileWatcher(keyFile.getParent());
|
||||
watcher.addListener(new FileListener(listeners));
|
||||
try {
|
||||
watcherService.add(watcher, ResourceWatcherService.Frequency.HIGH);
|
||||
} catch (IOException e) {
|
||||
throw new ElasticsearchException("failed to start watching system key file [" + keyFile.toAbsolutePath() + "]", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ElasticsearchException {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doClose() throws ElasticsearchException {
|
||||
}
|
||||
|
||||
private void loadKeys() {
|
||||
keyFile = resolveSystemKey(settings, env);
|
||||
systemKey = readSystemKey(keyFile);
|
||||
randomKey = generateSecretKey(RANDOM_KEY_SIZE);
|
||||
@ -144,6 +106,7 @@ public class InternalCryptoService extends AbstractLifecycleComponent implements
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
throw new ElasticsearchException("failed to start crypto service. could not load encryption key", nsae);
|
||||
}
|
||||
logger.info("system key [{}] has been loaded", keyFile.toAbsolutePath());
|
||||
}
|
||||
|
||||
public static byte[] generateKey() {
|
||||
@ -194,23 +157,12 @@ public class InternalCryptoService extends AbstractLifecycleComponent implements
|
||||
|
||||
@Override
|
||||
public String sign(String text) throws IOException {
|
||||
return sign(text, this.signingKey, this.systemKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sign(String text, SecretKey signingKey, @Nullable SecretKey systemKey) throws IOException {
|
||||
assert signingKey != null;
|
||||
String sigStr = signInternal(text, signingKey);
|
||||
return "$$" + sigStr.length() + "$$" + (systemKey == signingKey ? "" : randomKeyBase64) + "$$" + sigStr + text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String unsignAndVerify(String signedText) {
|
||||
return unsignAndVerify(signedText, this.systemKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String unsignAndVerify(String signedText, SecretKey systemKey) {
|
||||
if (!signedText.startsWith("$$") || signedText.length() < 2) {
|
||||
throw new IllegalArgumentException("tampered signed text");
|
||||
}
|
||||
@ -276,7 +228,7 @@ public class InternalCryptoService extends AbstractLifecycleComponent implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean signed(String text) {
|
||||
public boolean isSigned(String text) {
|
||||
return SIG_PATTERN.matcher(text).matches();
|
||||
}
|
||||
|
||||
@ -294,33 +246,13 @@ public class InternalCryptoService extends AbstractLifecycleComponent implements
|
||||
return ENCRYPTED_TEXT_PREFIX.concat(base64).toCharArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encrypt(byte[] bytes) {
|
||||
SecretKey key = this.encryptionKey;
|
||||
if (key == null) {
|
||||
logger.warn("encrypt called without a key, returning plain text. run syskeygen and copy same key to all nodes to enable " +
|
||||
"encryption");
|
||||
return bytes;
|
||||
}
|
||||
byte[] encrypted = encryptInternal(bytes, key);
|
||||
byte[] prefixed = new byte[ENCRYPTED_BYTE_PREFIX.length + encrypted.length];
|
||||
System.arraycopy(ENCRYPTED_BYTE_PREFIX, 0, prefixed, 0, ENCRYPTED_BYTE_PREFIX.length);
|
||||
System.arraycopy(encrypted, 0, prefixed, ENCRYPTED_BYTE_PREFIX.length, encrypted.length);
|
||||
return prefixed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] decrypt(char[] chars) {
|
||||
return decrypt(chars, this.encryptionKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] decrypt(char[] chars, SecretKey key) {
|
||||
if (key == null) {
|
||||
if (encryptionKey == null) {
|
||||
return chars;
|
||||
}
|
||||
|
||||
if (!encrypted(chars)) {
|
||||
if (!isEncrypted(chars)) {
|
||||
// Not encrypted
|
||||
return chars;
|
||||
}
|
||||
@ -333,46 +265,17 @@ public class InternalCryptoService extends AbstractLifecycleComponent implements
|
||||
throw new ElasticsearchException("unable to decode encrypted data", e);
|
||||
}
|
||||
|
||||
byte[] decrypted = decryptInternal(bytes, key);
|
||||
byte[] decrypted = decryptInternal(bytes, encryptionKey);
|
||||
return CharArrays.utf8BytesToChars(decrypted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decrypt(byte[] bytes) {
|
||||
return decrypt(bytes, this.encryptionKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decrypt(byte[] bytes, SecretKey key) {
|
||||
if (key == null) {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
if (!encrypted(bytes)) {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
byte[] encrypted = Arrays.copyOfRange(bytes, ENCRYPTED_BYTE_PREFIX.length, bytes.length);
|
||||
return decryptInternal(encrypted, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean encrypted(char[] chars) {
|
||||
public boolean isEncrypted(char[] chars) {
|
||||
return CharArrays.charsBeginsWith(ENCRYPTED_TEXT_PREFIX, chars);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean encrypted(byte[] bytes) {
|
||||
return bytesBeginsWith(ENCRYPTED_BYTE_PREFIX, bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Listener listener) {
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean encryptionEnabled() {
|
||||
public boolean isEncryptionEnabled() {
|
||||
return this.encryptionKey != null;
|
||||
}
|
||||
|
||||
@ -459,105 +362,6 @@ public class InternalCryptoService extends AbstractLifecycleComponent implements
|
||||
return new SecretKeySpec(truncatedDigest, algorithm);
|
||||
}
|
||||
|
||||
private static boolean bytesBeginsWith(byte[] prefix, byte[] bytes) {
|
||||
if (bytes == null || prefix == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prefix.length > bytes.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < prefix.length; i++) {
|
||||
if (bytes[i] != prefix[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private class FileListener extends FileChangesListener {
|
||||
|
||||
private final List<Listener> listeners;
|
||||
|
||||
private FileListener(List<Listener> listeners) {
|
||||
this.listeners = listeners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileCreated(Path file) {
|
||||
if (file.equals(keyFile)) {
|
||||
final SecretKey oldSystemKey = systemKey;
|
||||
final SecretKey oldEncryptionKey = encryptionKey;
|
||||
|
||||
systemKey = readSystemKey(file);
|
||||
signingKey = createSigningKey(systemKey, randomKey);
|
||||
try {
|
||||
encryptionKey = encryptionKey(signingKey, keyLength, keyAlgorithm);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
logger.error("could not load encryption key", nsae);
|
||||
encryptionKey = null;
|
||||
}
|
||||
logger.info("system key [{}] has been loaded", file.toAbsolutePath());
|
||||
callListeners(oldSystemKey, oldEncryptionKey);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileDeleted(Path file) {
|
||||
if (file.equals(keyFile)) {
|
||||
final SecretKey oldSystemKey = systemKey;
|
||||
final SecretKey oldEncryptionKey = encryptionKey;
|
||||
logger.error("system key file was removed! as long as the system key file is missing, elasticsearch " +
|
||||
"won't function as expected for some requests (e.g. scroll/scan)");
|
||||
systemKey = null;
|
||||
encryptionKey = null;
|
||||
signingKey = createSigningKey(systemKey, randomKey);
|
||||
|
||||
callListeners(oldSystemKey, oldEncryptionKey);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileChanged(Path file) {
|
||||
if (file.equals(keyFile)) {
|
||||
final SecretKey oldSystemKey = systemKey;
|
||||
final SecretKey oldEncryptionKey = encryptionKey;
|
||||
|
||||
logger.warn("system key file changed!");
|
||||
SecretKey systemKey = readSystemKey(file);
|
||||
signingKey = createSigningKey(systemKey, randomKey);
|
||||
try {
|
||||
encryptionKey = encryptionKey(signingKey, keyLength, keyAlgorithm);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
logger.error("could not load encryption key", nsae);
|
||||
encryptionKey = null;
|
||||
}
|
||||
|
||||
callListeners(oldSystemKey, oldEncryptionKey);
|
||||
}
|
||||
}
|
||||
|
||||
private void callListeners(SecretKey oldSystemKey, SecretKey oldEncryptionKey) {
|
||||
RuntimeException ex = null;
|
||||
for (Listener listener : listeners) {
|
||||
try {
|
||||
listener.onKeyChange(oldSystemKey, oldEncryptionKey);
|
||||
} catch (Exception e) {
|
||||
if (ex == null) ex = new RuntimeException("exception calling key change listeners");
|
||||
ex.addSuppressed(e);
|
||||
}
|
||||
}
|
||||
|
||||
// all listeners were notified now rethrow
|
||||
if (ex != null) {
|
||||
logger.error("called all key change listeners but one or more exceptions was thrown", ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider class for the HmacSHA1 {@link Mac} that provides an optimization by using a thread local instead of calling
|
||||
* Mac#getInstance and obtaining a lock (in the internals)
|
||||
|
@ -31,6 +31,7 @@ import org.jboss.netty.handler.ssl.SslHandler;
|
||||
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
@ -111,7 +112,7 @@ public class SecurityNettyTransport extends NettyTransport {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onException(Channel channel, Exception e) {
|
||||
protected void onException(Channel channel, Exception e) throws IOException {
|
||||
if (isNotSslRecordException(e)) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("received plaintext traffic on a encrypted channel, closing connection {}", e, channel);
|
||||
|
@ -84,7 +84,7 @@ public class BulkUpdateTests extends SecurityIntegTestCase {
|
||||
assertThat(response.getStatusLine().getStatusCode(), equalTo(201));
|
||||
}
|
||||
|
||||
try (Response response = getRestClient().performRequest("GET", path, Collections.emptyMap(), null, basicAuthHeader)) {
|
||||
try (Response response = getRestClient().performRequest("GET", path, basicAuthHeader)) {
|
||||
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
|
||||
assertThat(EntityUtils.toString(response.getEntity()), containsString("\"test\":\"test\""));
|
||||
}
|
||||
@ -100,7 +100,7 @@ public class BulkUpdateTests extends SecurityIntegTestCase {
|
||||
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
|
||||
}
|
||||
|
||||
try (Response response = getRestClient().performRequest("GET", path, Collections.emptyMap(), null, basicAuthHeader)) {
|
||||
try (Response response = getRestClient().performRequest("GET", path, basicAuthHeader)) {
|
||||
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
|
||||
String responseBody = EntityUtils.toString(response.getEntity());
|
||||
assertThat(responseBody, containsString("\"test\":\"test\""));
|
||||
@ -118,7 +118,7 @@ public class BulkUpdateTests extends SecurityIntegTestCase {
|
||||
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
|
||||
}
|
||||
|
||||
try (Response response = getRestClient().performRequest("GET", path, Collections.emptyMap(), null, basicAuthHeader)) {
|
||||
try (Response response = getRestClient().performRequest("GET", path, basicAuthHeader)) {
|
||||
String responseBody = EntityUtils.toString(response.getEntity());
|
||||
assertThat(responseBody, containsString("\"test\":\"test\""));
|
||||
assertThat(responseBody, containsString("\"not test\":\"not test\""));
|
||||
|
@ -162,7 +162,7 @@ public class ClearRealmsCacheTests extends SecurityIntegTestCase {
|
||||
}
|
||||
|
||||
static void executeHttpRequest(String path, Map<String, String> params) throws Exception {
|
||||
try (Response response = getRestClient().performRequest("POST", path, params, null,
|
||||
try (Response response = getRestClient().performRequest("POST", path, params,
|
||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||
UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.DEFAULT_USER_NAME,
|
||||
new SecuredString(SecuritySettingsSource.DEFAULT_PASSWORD.toCharArray()))))) {
|
||||
|
@ -15,6 +15,8 @@ import org.elasticsearch.common.network.NetworkModule;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.test.NativeRealmIntegTestCase;
|
||||
import org.elasticsearch.test.SecuritySettingsSource;
|
||||
import org.elasticsearch.xpack.security.SecurityTemplateService;
|
||||
import org.elasticsearch.xpack.security.action.role.GetRolesResponse;
|
||||
import org.elasticsearch.xpack.security.action.role.PutRoleResponse;
|
||||
@ -23,13 +25,10 @@ import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
||||
import org.elasticsearch.xpack.security.authz.RoleDescriptor;
|
||||
import org.elasticsearch.xpack.security.authz.store.NativeRolesStore;
|
||||
import org.elasticsearch.xpack.security.client.SecurityClient;
|
||||
import org.elasticsearch.test.NativeRealmIntegTestCase;
|
||||
import org.elasticsearch.test.SecuritySettingsSource;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
|
||||
@ -138,7 +137,7 @@ public class ClearRolesCacheTests extends NativeRealmIntegTestCase {
|
||||
} else {
|
||||
path = "/_xpack/security/role/" + Strings.arrayToCommaDelimitedString(rolesToClear) + "/_clear_cache";
|
||||
}
|
||||
try (Response response = getRestClient().performRequest("POST", path, Collections.emptyMap(), null,
|
||||
try (Response response = getRestClient().performRequest("POST", path,
|
||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||
UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.DEFAULT_USER_NAME,
|
||||
new SecuredString(SecuritySettingsSource.DEFAULT_PASSWORD.toCharArray()))))) {
|
||||
|
@ -305,7 +305,7 @@ public class IndexPrivilegeTests extends AbstractPrivilegeTestCase {
|
||||
|
||||
public void testThatUnknownUserIsRejectedProperly() throws Exception {
|
||||
try {
|
||||
getRestClient().performRequest("GET", "/", Collections.emptyMap(), null,
|
||||
getRestClient().performRequest("GET", "/",
|
||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||
UsernamePasswordToken.basicAuthHeaderValue("idonotexist", new SecuredString("passwd".toCharArray()))));
|
||||
fail("request should have failed");
|
||||
|
@ -168,7 +168,7 @@ public class LicensingTests extends SecurityIntegTestCase {
|
||||
}
|
||||
|
||||
public void testRestAuthenticationByLicenseType() throws Exception {
|
||||
try (Response response = getRestClient().performRequest("GET", "/", Collections.emptyMap(), null)) {
|
||||
try (Response response = getRestClient().performRequest("GET", "/")) {
|
||||
// the default of the licensing tests is basic
|
||||
assertThat(response.getStatusLine().getStatusCode(), is(200));
|
||||
}
|
||||
@ -177,7 +177,7 @@ public class LicensingTests extends SecurityIntegTestCase {
|
||||
OperationMode mode = randomFrom(OperationMode.GOLD, OperationMode.TRIAL, OperationMode.PLATINUM, OperationMode.STANDARD);
|
||||
enableLicensing(mode);
|
||||
try {
|
||||
getRestClient().performRequest("GET", "/", Collections.emptyMap(), null);
|
||||
getRestClient().performRequest("GET", "/");
|
||||
fail("request should have failed");
|
||||
} catch(ResponseException e) {
|
||||
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(401));
|
||||
|
@ -108,6 +108,6 @@ public class ScrollIdSigningTests extends SecurityIntegTestCase {
|
||||
private void assertSigned(String scrollId) {
|
||||
CryptoService cryptoService = internalCluster().getDataNodeInstance(InternalCryptoService.class);
|
||||
String message = String.format(Locale.ROOT, "Expected scrollId [%s] to be signed, but was not", scrollId);
|
||||
assertThat(message, cryptoService.signed(scrollId), is(true));
|
||||
assertThat(message, cryptoService.isSigned(scrollId), is(true));
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
||||
import org.elasticsearch.common.transport.TransportAddress;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.transport.MockTcpTransportPlugin;
|
||||
import org.elasticsearch.xpack.security.InternalClient;
|
||||
import org.elasticsearch.xpack.security.Security;
|
||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||
@ -177,11 +178,8 @@ public abstract class SecurityIntegTestCase extends ESIntegTestCase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> getMockPlugins() {
|
||||
Set<Class<? extends Plugin>> plugins = new HashSet<>(super.getMockPlugins());
|
||||
plugins.remove(MockTransportService.TestPlugin.class); // security has its own transport service
|
||||
plugins.remove(AssertingLocalTransport.TestPlugin.class); // security has its own transport
|
||||
return plugins;
|
||||
protected boolean addMockTransportService() {
|
||||
return false; // security has its own transport service
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -355,10 +353,6 @@ public abstract class SecurityIntegTestCase extends ESIntegTestCase {
|
||||
return internalCluster().getInstance(InternalClient.class);
|
||||
}
|
||||
|
||||
protected InternalClient internalClient(String node) {
|
||||
return internalCluster().getInstance(InternalClient.class, node);
|
||||
}
|
||||
|
||||
protected SecurityClient securityClient() {
|
||||
return securityClient(client());
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ public class SecurityFeatureSetTests extends ESTestCase {
|
||||
public void testSystemKeyUsageEnabledByCryptoService() {
|
||||
final boolean enabled = randomBoolean();
|
||||
|
||||
when(cryptoService.encryptionEnabled()).thenReturn(enabled);
|
||||
when(cryptoService.isEncryptionEnabled()).thenReturn(enabled);
|
||||
|
||||
assertThat(SecurityFeatureSet.systemKeyUsage(cryptoService), is(enabled));
|
||||
}
|
||||
@ -143,7 +143,7 @@ public class SecurityFeatureSetTests extends ESTestCase {
|
||||
when(rolesStore.usageStats()).thenReturn(Collections.emptyMap());
|
||||
}
|
||||
final boolean useSystemKey = randomBoolean();
|
||||
when(cryptoService.encryptionEnabled()).thenReturn(useSystemKey);
|
||||
when(cryptoService.isEncryptionEnabled()).thenReturn(useSystemKey);
|
||||
|
||||
List<Realm> realmsList= new ArrayList<>();
|
||||
|
||||
|
@ -9,13 +9,12 @@ import org.apache.http.message.BasicHeader;
|
||||
import org.elasticsearch.client.Response;
|
||||
import org.elasticsearch.client.ResponseException;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
||||
import org.elasticsearch.test.SecurityIntegTestCase;
|
||||
import org.elasticsearch.test.SecuritySettingsSource;
|
||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.elasticsearch.rest.RestStatus.OK;
|
||||
import static org.elasticsearch.rest.RestStatus.UNAUTHORIZED;
|
||||
@ -35,14 +34,14 @@ public class SecurityPluginTests extends SecurityIntegTestCase {
|
||||
public void testThatPluginIsLoaded() throws IOException {
|
||||
try {
|
||||
logger.info("executing unauthorized request to /_xpack info");
|
||||
getRestClient().performRequest("GET", "/_xpack", Collections.emptyMap(), null);
|
||||
getRestClient().performRequest("GET", "/_xpack");
|
||||
fail("request should have failed");
|
||||
} catch(ResponseException e) {
|
||||
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(UNAUTHORIZED.getStatus()));
|
||||
}
|
||||
|
||||
logger.info("executing authorized request to /_xpack infos");
|
||||
try (Response response = getRestClient().performRequest("GET", "/_xpack", Collections.emptyMap(), null,
|
||||
try (Response response = getRestClient().performRequest("GET", "/_xpack",
|
||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||
basicAuthHeaderValue(SecuritySettingsSource.DEFAULT_USER_NAME,
|
||||
new SecuredString(SecuritySettingsSource.DEFAULT_PASSWORD.toCharArray()))))) {
|
||||
|
@ -105,7 +105,7 @@ public class SecurityActionFilterTests extends ESTestCase {
|
||||
Task task = mock(Task.class);
|
||||
Authentication authentication = new Authentication(user, new RealmRef("test", "test", "foo"), null);
|
||||
when(authcService.authenticate("_action", request, SystemUser.INSTANCE)).thenReturn(authentication);
|
||||
when(cryptoService.signed("signed_scroll_id")).thenReturn(true);
|
||||
when(cryptoService.isSigned("signed_scroll_id")).thenReturn(true);
|
||||
when(cryptoService.unsignAndVerify("signed_scroll_id")).thenReturn("scroll_id");
|
||||
filter.apply(task, "_action", request, listener, chain);
|
||||
assertThat(request.scrollId(), equalTo("scroll_id"));
|
||||
@ -122,7 +122,7 @@ public class SecurityActionFilterTests extends ESTestCase {
|
||||
Task task = mock(Task.class);
|
||||
Authentication authentication = new Authentication(user, new RealmRef("test", "test", "foo"), null);
|
||||
when(authcService.authenticate("_action", request, SystemUser.INSTANCE)).thenReturn(authentication);
|
||||
when(cryptoService.signed("scroll_id")).thenReturn(true);
|
||||
when(cryptoService.isSigned("scroll_id")).thenReturn(true);
|
||||
doThrow(sigException).when(cryptoService).unsignAndVerify("scroll_id");
|
||||
filter.apply(task, "_action", request, listener, chain);
|
||||
verify(listener).onFailure(isA(ElasticsearchSecurityException.class));
|
||||
|
@ -91,10 +91,11 @@ public class TransportGetUsersActionTests extends ESTestCase {
|
||||
|
||||
assertThat(throwableRef.get(), is(nullValue()));
|
||||
assertThat(responseRef.get(), is(notNullValue()));
|
||||
final User[] users = responseRef.get().users();
|
||||
if (anonymousEnabled) {
|
||||
assertThat(responseRef.get().users(), arrayContaining(AnonymousUser.INSTANCE));
|
||||
assertThat("expected array with anonymous but got: " + Arrays.toString(users), users, arrayContaining(AnonymousUser.INSTANCE));
|
||||
} else {
|
||||
assertThat(responseRef.get().users(), emptyArray());
|
||||
assertThat("expected an empty array but got: " + Arrays.toString(users), users, emptyArray());
|
||||
}
|
||||
verifyZeroInteractions(usersStore);
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ public class RunAsIntegTests extends SecurityIntegTestCase {
|
||||
public void testUserImpersonationUsingHttp() throws Exception {
|
||||
// use the transport client user and try to run as
|
||||
try {
|
||||
getRestClient().performRequest("GET", "/_nodes", Collections.emptyMap(), null,
|
||||
getRestClient().performRequest("GET", "/_nodes",
|
||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||
UsernamePasswordToken.basicAuthHeaderValue(TRANSPORT_CLIENT_USER,
|
||||
SecuredStringTests.build(SecuritySettingsSource.DEFAULT_PASSWORD))),
|
||||
@ -130,7 +130,7 @@ public class RunAsIntegTests extends SecurityIntegTestCase {
|
||||
|
||||
try {
|
||||
//the run as user shouldn't have access to the nodes api
|
||||
getRestClient().performRequest("GET", "/_nodes", Collections.emptyMap(), null,
|
||||
getRestClient().performRequest("GET", "/_nodes",
|
||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||
UsernamePasswordToken.basicAuthHeaderValue(RUN_AS_USER,
|
||||
SecuredStringTests.build(SecuritySettingsSource.DEFAULT_PASSWORD))));
|
||||
@ -140,7 +140,7 @@ public class RunAsIntegTests extends SecurityIntegTestCase {
|
||||
}
|
||||
|
||||
// but when running as a different user it should work
|
||||
try (Response response = getRestClient().performRequest("GET", "/_nodes", Collections.emptyMap(), null,
|
||||
try (Response response = getRestClient().performRequest("GET", "/_nodes",
|
||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||
UsernamePasswordToken.basicAuthHeaderValue(RUN_AS_USER,
|
||||
SecuredStringTests.build(SecuritySettingsSource.DEFAULT_PASSWORD))),
|
||||
@ -173,7 +173,7 @@ public class RunAsIntegTests extends SecurityIntegTestCase {
|
||||
|
||||
public void testEmptyHeaderUsingHttp() throws Exception {
|
||||
try {
|
||||
getRestClient().performRequest("GET", "/_nodes", Collections.emptyMap(), null,
|
||||
getRestClient().performRequest("GET", "/_nodes",
|
||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||
UsernamePasswordToken.basicAuthHeaderValue(RUN_AS_USER,
|
||||
SecuredStringTests.build(SecuritySettingsSource.DEFAULT_PASSWORD))),
|
||||
@ -208,7 +208,7 @@ public class RunAsIntegTests extends SecurityIntegTestCase {
|
||||
|
||||
public void testNonExistentRunAsUserUsingHttp() throws Exception {
|
||||
try {
|
||||
getRestClient().performRequest("GET", "/_nodes", Collections.emptyMap(), null,
|
||||
getRestClient().performRequest("GET", "/_nodes",
|
||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||
UsernamePasswordToken.basicAuthHeaderValue(RUN_AS_USER,
|
||||
SecuredStringTests.build(SecuritySettingsSource.DEFAULT_PASSWORD))),
|
||||
|
@ -99,7 +99,7 @@ public class PkiAuthenticationTests extends SecurityIntegTestCase {
|
||||
|
||||
public void testRestAuthenticationViaPki() throws Exception {
|
||||
SSLContext context = getRestSSLContext("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.jks", "testnode");
|
||||
try (CloseableHttpClient client = HttpClients.custom().setSslcontext(context).build()) {
|
||||
try (CloseableHttpClient client = HttpClients.custom().setSSLContext(context).build()) {
|
||||
HttpPut put = new HttpPut(getNodeUrl() + "foo");
|
||||
try (CloseableHttpResponse response = client.execute(put)) {
|
||||
String body = EntityUtils.toString(response.getEntity());
|
||||
@ -110,7 +110,7 @@ public class PkiAuthenticationTests extends SecurityIntegTestCase {
|
||||
|
||||
public void testRestAuthenticationFailure() throws Exception {
|
||||
SSLContext context = getRestSSLContext("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks", "testclient");
|
||||
try (CloseableHttpClient client = HttpClients.custom().setSslcontext(context).build()) {
|
||||
try (CloseableHttpClient client = HttpClients.custom().setSSLContext(context).build()) {
|
||||
HttpPut put = new HttpPut(getNodeUrl() + "foo");
|
||||
try (CloseableHttpResponse response = client.execute(put)) {
|
||||
assertThat(response.getStatusLine().getStatusCode(), is(401));
|
||||
|
@ -35,7 +35,6 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.KeyStore;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.elasticsearch.test.SecuritySettingsSource.DEFAULT_PASSWORD;
|
||||
import static org.elasticsearch.test.SecuritySettingsSource.DEFAULT_USER_NAME;
|
||||
@ -83,13 +82,13 @@ public class PkiOptionalClientAuthTests extends SecurityIntegTestCase {
|
||||
CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(getSSLContext()).build();
|
||||
try (RestClient restClient = createRestClient(httpClient, "https")) {
|
||||
try {
|
||||
restClient.performRequest("GET", "_nodes", Collections.emptyMap(), null);
|
||||
restClient.performRequest("GET", "_nodes");
|
||||
fail("request should have failed");
|
||||
} catch(ResponseException e) {
|
||||
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(401));
|
||||
}
|
||||
|
||||
try (Response response = restClient.performRequest("GET", "_nodes", Collections.emptyMap(), null,
|
||||
try (Response response = restClient.performRequest("GET", "_nodes",
|
||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||
UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.DEFAULT_USER_NAME,
|
||||
new SecuredString(SecuritySettingsSource.DEFAULT_PASSWORD.toCharArray()))))) {
|
||||
|
@ -28,7 +28,6 @@ import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
@ -81,7 +80,7 @@ public class PkiWithoutClientAuthenticationTests extends SecurityIntegTestCase {
|
||||
sc.init(null, trustAllCerts, new SecureRandom());
|
||||
CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(sc).build();
|
||||
try (RestClient restClient = createRestClient(httpClient, "https")) {
|
||||
try (Response response = restClient.performRequest("GET", "/_nodes", Collections.emptyMap(), null,
|
||||
try (Response response = restClient.performRequest("GET", "/_nodes",
|
||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||
UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.DEFAULT_USER_NAME,
|
||||
new SecuredString(SecuritySettingsSource.DEFAULT_PASSWORD.toCharArray()))))) {
|
||||
|
@ -16,8 +16,6 @@ import org.elasticsearch.test.SecuritySettingsSource;
|
||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
@ClusterScope(numClientNodes = 0, supportsDedicatedMasters = false, numDataNodes = 1)
|
||||
@ -43,7 +41,7 @@ public class PkiWithoutSSLTests extends SecurityIntegTestCase {
|
||||
}
|
||||
|
||||
public void testThatHttpWorks() throws Exception {
|
||||
try (Response response = getRestClient().performRequest("GET", "/_nodes", Collections.emptyMap(), null,
|
||||
try (Response response = getRestClient().performRequest("GET", "/_nodes",
|
||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||
UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.DEFAULT_USER_NAME,
|
||||
new SecuredString(SecuritySettingsSource.DEFAULT_PASSWORD.toCharArray()))))) {
|
||||
|
@ -5,28 +5,16 @@
|
||||
*/
|
||||
package org.elasticsearch.xpack.security.crypto;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.common.io.Streams;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.threadpool.TestThreadPool;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.junit.Before;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
@ -34,15 +22,10 @@ import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class InternalCryptoServiceTests extends ESTestCase {
|
||||
private ResourceWatcherService watcherService;
|
||||
private Settings settings;
|
||||
private Environment env;
|
||||
private Path keyFile;
|
||||
private ThreadPool threadPool;
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
@ -54,30 +37,19 @@ public class InternalCryptoServiceTests extends ESTestCase {
|
||||
.put("path.home", createTempDir())
|
||||
.build();
|
||||
env = new Environment(settings);
|
||||
threadPool = new TestThreadPool("test");
|
||||
watcherService = new ResourceWatcherService(settings, threadPool);
|
||||
watcherService.start();
|
||||
}
|
||||
|
||||
@After
|
||||
public void shutdown() throws InterruptedException {
|
||||
watcherService.stop();
|
||||
terminate(threadPool);
|
||||
}
|
||||
|
||||
public void testSigned() throws Exception {
|
||||
// randomize whether to use a system key or not
|
||||
Settings settings = randomBoolean() ? this.settings : Settings.EMPTY;
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env);
|
||||
String text = randomAsciiOfLength(10);
|
||||
String signed = service.sign(text);
|
||||
assertThat(service.signed(signed), is(true));
|
||||
assertThat(service.isSigned(signed), is(true));
|
||||
}
|
||||
|
||||
public void testSignAndUnsign() throws Exception {
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env);
|
||||
String text = randomAsciiOfLength(10);
|
||||
String signed = service.sign(text);
|
||||
assertThat(text.equals(signed), is(false));
|
||||
@ -86,8 +58,7 @@ public class InternalCryptoServiceTests extends ESTestCase {
|
||||
}
|
||||
|
||||
public void testSignAndUnsignNoKeyFile() throws Exception {
|
||||
InternalCryptoService service = new InternalCryptoService(Settings.EMPTY, env, watcherService);
|
||||
service.start();
|
||||
InternalCryptoService service = new InternalCryptoService(Settings.EMPTY, env);
|
||||
final String text = randomAsciiOfLength(10);
|
||||
String signed = service.sign(text);
|
||||
// we always have some sort of key to sign with
|
||||
@ -97,8 +68,7 @@ public class InternalCryptoServiceTests extends ESTestCase {
|
||||
}
|
||||
|
||||
public void testTamperedSignature() throws Exception {
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env);
|
||||
String text = randomAsciiOfLength(10);
|
||||
String signed = service.sign(text);
|
||||
int i = signed.indexOf("$$", 2);
|
||||
@ -115,8 +85,7 @@ public class InternalCryptoServiceTests extends ESTestCase {
|
||||
}
|
||||
|
||||
public void testTamperedSignatureOneChar() throws Exception {
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env);
|
||||
String text = randomAsciiOfLength(10);
|
||||
String signed = service.sign(text);
|
||||
int i = signed.indexOf("$$", 2);
|
||||
@ -135,8 +104,7 @@ public class InternalCryptoServiceTests extends ESTestCase {
|
||||
}
|
||||
|
||||
public void testTamperedSignatureLength() throws Exception {
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env);
|
||||
String text = randomAsciiOfLength(10);
|
||||
String signed = service.sign(text);
|
||||
int i = signed.indexOf("$$", 2);
|
||||
@ -162,10 +130,9 @@ public class InternalCryptoServiceTests extends ESTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testEncryptionAndDecryptionChars() {
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
assertThat(service.encryptionEnabled(), is(true));
|
||||
public void testEncryptionAndDecryptionChars() throws Exception {
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env);
|
||||
assertThat(service.isEncryptionEnabled(), is(true));
|
||||
final char[] chars = randomAsciiOfLengthBetween(0, 1000).toCharArray();
|
||||
final char[] encrypted = service.encrypt(chars);
|
||||
assertThat(encrypted, notNullValue());
|
||||
@ -175,23 +142,9 @@ public class InternalCryptoServiceTests extends ESTestCase {
|
||||
assertThat(Arrays.equals(chars, decrypted), is(true));
|
||||
}
|
||||
|
||||
public void testEncryptionAndDecryptionBytes() {
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
assertThat(service.encryptionEnabled(), is(true));
|
||||
final byte[] bytes = randomByteArray();
|
||||
final byte[] encrypted = service.encrypt(bytes);
|
||||
assertThat(encrypted, notNullValue());
|
||||
assertThat(Arrays.equals(encrypted, bytes), is(false));
|
||||
|
||||
final byte[] decrypted = service.decrypt(encrypted);
|
||||
assertThat(Arrays.equals(bytes, decrypted), is(true));
|
||||
}
|
||||
|
||||
public void testEncryptionAndDecryptionCharsWithoutKey() {
|
||||
InternalCryptoService service = new InternalCryptoService(Settings.EMPTY, env, watcherService);
|
||||
service.start();
|
||||
assertThat(service.encryptionEnabled(), is(false));
|
||||
public void testEncryptionAndDecryptionCharsWithoutKey() throws Exception {
|
||||
InternalCryptoService service = new InternalCryptoService(Settings.EMPTY, env);
|
||||
assertThat(service.isEncryptionEnabled(), is(false));
|
||||
final char[] chars = randomAsciiOfLengthBetween(0, 1000).toCharArray();
|
||||
final char[] encryptedChars = service.encrypt(chars);
|
||||
final char[] decryptedChars = service.decrypt(encryptedChars);
|
||||
@ -199,288 +152,26 @@ public class InternalCryptoServiceTests extends ESTestCase {
|
||||
assertThat(chars, equalTo(decryptedChars));
|
||||
}
|
||||
|
||||
public void testEncryptionAndDecryptionBytesWithoutKey() {
|
||||
InternalCryptoService service = new InternalCryptoService(Settings.EMPTY, env, watcherService);
|
||||
service.start();
|
||||
assertThat(service.encryptionEnabled(), is(false));
|
||||
final byte[] bytes = randomByteArray();
|
||||
final byte[] encryptedBytes = service.encrypt(bytes);
|
||||
final byte[] decryptedBytes = service.decrypt(bytes);
|
||||
assertThat(bytes, equalTo(encryptedBytes));
|
||||
assertThat(decryptedBytes, equalTo(encryptedBytes));
|
||||
public void testEncryptionEnabledWithKey() throws Exception {
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env);
|
||||
assertThat(service.isEncryptionEnabled(), is(true));
|
||||
}
|
||||
|
||||
public void testEncryptionEnabledWithKey() {
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
assertThat(service.encryptionEnabled(), is(true));
|
||||
public void testEncryptionEnabledWithoutKey() throws Exception {
|
||||
InternalCryptoService service = new InternalCryptoService(Settings.EMPTY, env);
|
||||
assertThat(service.isEncryptionEnabled(), is(false));
|
||||
}
|
||||
|
||||
public void testEncryptionEnabledWithoutKey() {
|
||||
InternalCryptoService service = new InternalCryptoService(Settings.EMPTY, env, watcherService);
|
||||
service.start();
|
||||
assertThat(service.encryptionEnabled(), is(false));
|
||||
}
|
||||
public void testEncryptedChar() throws Exception {
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env);
|
||||
assertThat(service.isEncryptionEnabled(), is(true));
|
||||
|
||||
public void testChangingAByte() {
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
assertThat(service.encryptionEnabled(), is(true));
|
||||
// We need at least one byte to test changing a byte, otherwise output is always the same
|
||||
final byte[] bytes = randomByteArray(1);
|
||||
final byte[] encrypted = service.encrypt(bytes);
|
||||
assertThat(encrypted, notNullValue());
|
||||
assertThat(Arrays.equals(encrypted, bytes), is(false));
|
||||
|
||||
int tamperedIndex = randomIntBetween(InternalCryptoService.ENCRYPTED_BYTE_PREFIX.length, encrypted.length - 1);
|
||||
final byte untamperedByte = encrypted[tamperedIndex];
|
||||
byte tamperedByte = randomByte();
|
||||
while (tamperedByte == untamperedByte) {
|
||||
tamperedByte = randomByte();
|
||||
}
|
||||
encrypted[tamperedIndex] = tamperedByte;
|
||||
final byte[] decrypted = service.decrypt(encrypted);
|
||||
assertThat(Arrays.equals(bytes, decrypted), is(false));
|
||||
}
|
||||
|
||||
public void testEncryptedChar() {
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
assertThat(service.encryptionEnabled(), is(true));
|
||||
|
||||
assertThat(service.encrypted((char[]) null), is(false));
|
||||
assertThat(service.encrypted(new char[0]), is(false));
|
||||
assertThat(service.encrypted(new char[InternalCryptoService.ENCRYPTED_TEXT_PREFIX.length()]), is(false));
|
||||
assertThat(service.encrypted(InternalCryptoService.ENCRYPTED_TEXT_PREFIX.toCharArray()), is(true));
|
||||
assertThat(service.encrypted(randomAsciiOfLengthBetween(0, 100).toCharArray()), is(false));
|
||||
assertThat(service.encrypted(service.encrypt(randomAsciiOfLength(10).toCharArray())), is(true));
|
||||
}
|
||||
|
||||
public void testEncryptedByte() {
|
||||
InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
assertThat(service.encryptionEnabled(), is(true));
|
||||
|
||||
assertThat(service.encrypted((byte[]) null), is(false));
|
||||
assertThat(service.encrypted(new byte[0]), is(false));
|
||||
assertThat(service.encrypted(new byte[InternalCryptoService.ENCRYPTED_BYTE_PREFIX.length]), is(false));
|
||||
assertThat(service.encrypted(InternalCryptoService.ENCRYPTED_BYTE_PREFIX), is(true));
|
||||
assertThat(service.encrypted(randomAsciiOfLengthBetween(0, 100).getBytes(StandardCharsets.UTF_8)), is(false));
|
||||
assertThat(service.encrypted(service.encrypt(randomAsciiOfLength(10).getBytes(StandardCharsets.UTF_8))), is(true));
|
||||
}
|
||||
|
||||
public void testReloadKey() throws Exception {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final CryptoService.Listener listener = new CryptoService.Listener() {
|
||||
@Override
|
||||
public void onKeyChange(SecretKey oldSystemKey, SecretKey oldEncryptionKey) {
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
|
||||
// randomize how we set the listener
|
||||
InternalCryptoService service;
|
||||
if (randomBoolean()) {
|
||||
service = new InternalCryptoService(settings, env, watcherService, Collections.singletonList(listener));
|
||||
service.start();
|
||||
} else {
|
||||
service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
service.register(listener);
|
||||
}
|
||||
|
||||
String text = randomAsciiOfLength(10);
|
||||
String signed = service.sign(text);
|
||||
char[] textChars = text.toCharArray();
|
||||
char[] encrypted = service.encrypt(textChars);
|
||||
|
||||
// we need to sleep to ensure the timestamp of the file will definitely change
|
||||
// and so the resource watcher will pick up the change.
|
||||
Thread.sleep(1000L);
|
||||
|
||||
try (OutputStream os = Files.newOutputStream(keyFile)) {
|
||||
Streams.copy(InternalCryptoService.generateKey(), os);
|
||||
}
|
||||
if (!latch.await(10, TimeUnit.SECONDS)) {
|
||||
fail("waiting too long for test to complete. Expected callback is not called");
|
||||
}
|
||||
String signed2 = service.sign(text);
|
||||
assertThat(signed.equals(signed2), is(false));
|
||||
|
||||
char[] encrypted2 = service.encrypt(textChars);
|
||||
|
||||
char[] decrypted = service.decrypt(encrypted);
|
||||
char[] decrypted2 = service.decrypt(encrypted2);
|
||||
assertThat(Arrays.equals(textChars, decrypted), is(false));
|
||||
assertThat(Arrays.equals(textChars, decrypted2), is(true));
|
||||
}
|
||||
|
||||
public void testReencryptValuesOnKeyChange() throws Exception {
|
||||
final InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
assertThat(service.encryptionEnabled(), is(true));
|
||||
final char[] text = randomAsciiOfLength(10).toCharArray();
|
||||
final char[] encrypted = service.encrypt(text);
|
||||
assertThat(text, not(equalTo(encrypted)));
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
service.register(new CryptoService.Listener() {
|
||||
@Override
|
||||
public void onKeyChange(SecretKey oldSystemKey, SecretKey oldEncryptionKey) {
|
||||
final char[] plainText = service.decrypt(encrypted, oldEncryptionKey);
|
||||
assertThat(plainText, equalTo(text));
|
||||
final char[] newEncrypted = service.encrypt(plainText);
|
||||
assertThat(newEncrypted, not(equalTo(encrypted)));
|
||||
assertThat(newEncrypted, not(equalTo(plainText)));
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
// we need to sleep to ensure the timestamp of the file will definitely change
|
||||
// and so the resource watcher will pick up the change.
|
||||
Thread.sleep(1000);
|
||||
|
||||
Files.write(keyFile, InternalCryptoService.generateKey());
|
||||
if (!latch.await(10, TimeUnit.SECONDS)) {
|
||||
fail("waiting too long for test to complete. Expected callback is not called or finished running");
|
||||
}
|
||||
}
|
||||
|
||||
public void testResignValuesOnKeyChange() throws Exception {
|
||||
final InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
final String text = randomAsciiOfLength(10);
|
||||
final String signed = service.sign(text);
|
||||
assertThat(text, not(equalTo(signed)));
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
service.register(new CryptoService.Listener() {
|
||||
@Override
|
||||
public void onKeyChange(SecretKey oldSystemKey, SecretKey oldEncryptionKey) {
|
||||
try {
|
||||
assertThat(oldSystemKey, notNullValue());
|
||||
final String unsigned = service.unsignAndVerify(signed, oldSystemKey);
|
||||
assertThat(unsigned, equalTo(text));
|
||||
final String newSigned = service.sign(unsigned);
|
||||
assertThat(newSigned, not(equalTo(signed)));
|
||||
assertThat(newSigned, not(equalTo(text)));
|
||||
latch.countDown();
|
||||
} catch (IOException e) {
|
||||
logger.error("caught exception in key change listener", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// we need to sleep to ensure the timestamp of the file will definitely change
|
||||
// and so the resource watcher will pick up the change.
|
||||
Thread.sleep(1000);
|
||||
|
||||
Files.write(keyFile, InternalCryptoService.generateKey());
|
||||
if (!latch.await(10, TimeUnit.SECONDS)) {
|
||||
fail("waiting too long for test to complete. Expected callback is not called or finished running");
|
||||
}
|
||||
}
|
||||
|
||||
public void testReencryptValuesOnKeyDeleted() throws Exception {
|
||||
final InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
assertThat(service.encryptionEnabled(), is(true));
|
||||
final char[] text = randomAsciiOfLength(10).toCharArray();
|
||||
final char[] encrypted = service.encrypt(text);
|
||||
assertThat(text, not(equalTo(encrypted)));
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
service.register(new CryptoService.Listener() {
|
||||
@Override
|
||||
public void onKeyChange(SecretKey oldSystemKey, SecretKey oldEncryptionKey) {
|
||||
final char[] plainText = service.decrypt(encrypted, oldEncryptionKey);
|
||||
assertThat(plainText, equalTo(text));
|
||||
final char[] newEncrypted = service.encrypt(plainText);
|
||||
assertThat(newEncrypted, not(equalTo(encrypted)));
|
||||
assertThat(newEncrypted, equalTo(plainText));
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
// we need to sleep to ensure the timestamp of the file will definitely change
|
||||
// and so the resource watcher will pick up the change.
|
||||
Thread.sleep(1000);
|
||||
|
||||
Files.delete(keyFile);
|
||||
if (!latch.await(10, TimeUnit.SECONDS)) {
|
||||
fail("waiting too long for test to complete. Expected callback is not called or finished running");
|
||||
}
|
||||
}
|
||||
|
||||
public void testAllListenersCalledWhenExceptionThrown() throws Exception {
|
||||
final InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
assertThat(service.encryptionEnabled(), is(true));
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(3);
|
||||
service.register(new CryptoService.Listener() {
|
||||
@Override
|
||||
public void onKeyChange(SecretKey oldSystemKey, SecretKey oldEncryptionKey) {
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
service.register(new CryptoService.Listener() {
|
||||
@Override
|
||||
public void onKeyChange(SecretKey oldSystemKey, SecretKey oldEncryptionKey) {
|
||||
latch.countDown();
|
||||
throw new RuntimeException("misbehaving listener");
|
||||
}
|
||||
});
|
||||
service.register(new CryptoService.Listener() {
|
||||
@Override
|
||||
public void onKeyChange(SecretKey oldSystemKey, SecretKey oldEncryptionKey) {
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
// we need to sleep to ensure the timestamp of the file will definitely change
|
||||
// and so the resource watcher will pick up the change.
|
||||
Thread.sleep(1000);
|
||||
|
||||
Files.write(keyFile, InternalCryptoService.generateKey());
|
||||
if (!latch.await(10, TimeUnit.SECONDS)) {
|
||||
fail("waiting too long for test to complete. Expected callback is not called or finished running");
|
||||
}
|
||||
}
|
||||
|
||||
public void testSigningOnKeyDeleted() throws Exception {
|
||||
final InternalCryptoService service = new InternalCryptoService(settings, env, watcherService);
|
||||
service.start();
|
||||
final String text = randomAsciiOfLength(10);
|
||||
final String signed = service.sign(text);
|
||||
assertThat(text, not(equalTo(signed)));
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
service.register(new CryptoService.Listener() {
|
||||
@Override
|
||||
public void onKeyChange(SecretKey oldSystemKey, SecretKey oldEncryptionKey) {
|
||||
final String plainText = service.unsignAndVerify(signed, oldSystemKey);
|
||||
assertThat(plainText, equalTo(text));
|
||||
try {
|
||||
final String newSigned = service.sign(plainText);
|
||||
assertThat(newSigned, not(equalTo(signed)));
|
||||
assertThat(newSigned, not(equalTo(plainText)));
|
||||
assertThat(service.unsignAndVerify(newSigned), equalTo(plainText));
|
||||
latch.countDown();
|
||||
} catch (IOException e) {
|
||||
throw new ElasticsearchException("unexpected exception while signing", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// we need to sleep to ensure the timestamp of the file will definitely change
|
||||
// and so the resource watcher will pick up the change.
|
||||
Thread.sleep(1000);
|
||||
|
||||
Files.delete(keyFile);
|
||||
if (!latch.await(10, TimeUnit.SECONDS)) {
|
||||
fail("waiting too long for test to complete. Expected callback is not called or finished running");
|
||||
}
|
||||
assertThat(service.isEncrypted((char[]) null), is(false));
|
||||
assertThat(service.isEncrypted(new char[0]), is(false));
|
||||
assertThat(service.isEncrypted(new char[InternalCryptoService.ENCRYPTED_TEXT_PREFIX.length()]), is(false));
|
||||
assertThat(service.isEncrypted(InternalCryptoService.ENCRYPTED_TEXT_PREFIX.toCharArray()), is(true));
|
||||
assertThat(service.isEncrypted(randomAsciiOfLengthBetween(0, 100).toCharArray()), is(false));
|
||||
assertThat(service.isEncrypted(service.encrypt(randomAsciiOfLength(10).toCharArray())), is(true));
|
||||
}
|
||||
|
||||
public void testSigningKeyCanBeRecomputedConsistently() {
|
||||
@ -493,17 +184,4 @@ public class InternalCryptoServiceTests extends ESTestCase {
|
||||
assertThat(regenerated, equalTo(signingKey));
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] randomByteArray() {
|
||||
return randomByteArray(0);
|
||||
}
|
||||
|
||||
private static byte[] randomByteArray(int min) {
|
||||
int count = randomIntBetween(min, 1000);
|
||||
byte[] bytes = new byte[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
bytes[i] = randomByte();
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
@ -13,15 +13,14 @@ import org.elasticsearch.common.network.NetworkModule;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||
import org.elasticsearch.xpack.security.authz.InternalAuthorizationService;
|
||||
import org.elasticsearch.xpack.security.user.AnonymousUser;
|
||||
import org.elasticsearch.test.SecurityIntegTestCase;
|
||||
import org.elasticsearch.test.SecuritySettingsSource;
|
||||
import org.elasticsearch.test.rest.ObjectPath;
|
||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||
import org.elasticsearch.xpack.security.authz.InternalAuthorizationService;
|
||||
import org.elasticsearch.xpack.security.user.AnonymousUser;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||
@ -54,7 +53,7 @@ public class RestAuthenticateActionTests extends SecurityIntegTestCase {
|
||||
|
||||
public void testAuthenticateApi() throws Exception {
|
||||
try (Response response = getRestClient().performRequest(
|
||||
"GET", "/_xpack/security/_authenticate", Collections.emptyMap(), null,
|
||||
"GET", "/_xpack/security/_authenticate",
|
||||
new BasicHeader("Authorization", basicAuthHeaderValue(SecuritySettingsSource.DEFAULT_USER_NAME,
|
||||
new SecuredString(SecuritySettingsSource.DEFAULT_PASSWORD.toCharArray()))))) {
|
||||
assertThat(response.getStatusLine().getStatusCode(), is(200));
|
||||
@ -69,8 +68,7 @@ public class RestAuthenticateActionTests extends SecurityIntegTestCase {
|
||||
}
|
||||
|
||||
public void testAuthenticateApiWithoutAuthentication() throws Exception {
|
||||
try (Response response = getRestClient().performRequest("GET", "/_xpack/security/_authenticate",
|
||||
Collections.emptyMap(), null)) {
|
||||
try (Response response = getRestClient().performRequest("GET", "/_xpack/security/_authenticate")) {
|
||||
if (anonymousEnabled) {
|
||||
assertThat(response.getStatusLine().getStatusCode(), is(200));
|
||||
ObjectPath objectPath = ObjectPath.createFromXContent(XContentFactory.xContent(XContentType.JSON),
|
||||
|
@ -41,8 +41,8 @@ import static org.hamcrest.Matchers.sameInstance;
|
||||
|
||||
public class ClientSSLServiceTests extends ESTestCase {
|
||||
|
||||
Environment env;
|
||||
Path testclientStore;
|
||||
private Environment env;
|
||||
private Path testclientStore;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
@ -181,7 +181,7 @@ public class ClientSSLServiceTests extends ESTestCase {
|
||||
public void testThatSSLContextWithoutSettingsWorks() throws Exception {
|
||||
ClientSSLService sslService = createClientSSLService(Settings.EMPTY);
|
||||
SSLContext sslContext = sslService.sslContext();
|
||||
try (CloseableHttpClient client = HttpClients.custom().setSslcontext(sslContext).build()) {
|
||||
try (CloseableHttpClient client = HttpClients.custom().setSSLContext(sslContext).build()) {
|
||||
// Execute a GET on a site known to have a valid certificate signed by a trusted public CA
|
||||
// This will result in a SSLHandshakeException if the SSLContext does not trust the CA, but the default
|
||||
// truststore trusts all common public CAs so the handshake will succeed
|
||||
@ -196,7 +196,7 @@ public class ClientSSLServiceTests extends ESTestCase {
|
||||
.put("xpack.security.ssl.keystore.password", "testclient")
|
||||
.build());
|
||||
SSLContext sslContext = sslService.sslContext();
|
||||
try (CloseableHttpClient client = HttpClients.custom().setSslcontext(sslContext).build()) {
|
||||
try (CloseableHttpClient client = HttpClients.custom().setSSLContext(sslContext).build()) {
|
||||
// Execute a GET on a site known to have a valid certificate signed by a trusted public CA which will succeed because the JDK
|
||||
// certs are trusted by default
|
||||
client.execute(new HttpGet("https://www.elastic.co/")).close();
|
||||
@ -208,7 +208,7 @@ public class ClientSSLServiceTests extends ESTestCase {
|
||||
.put(Global.INCLUDE_JDK_CERTS_SETTING.getKey(), "false")
|
||||
.build());
|
||||
sslContext = sslService.sslContext();
|
||||
try (CloseableHttpClient client = HttpClients.custom().setSslcontext(sslContext).build()) {
|
||||
try (CloseableHttpClient client = HttpClients.custom().setSSLContext(sslContext).build()) {
|
||||
// Execute a GET on a site known to have a valid certificate signed by a trusted public CA
|
||||
// This will result in a SSLHandshakeException because the truststore is the testnodestore, which doesn't
|
||||
// trust any public CAs
|
||||
@ -283,7 +283,7 @@ public class ClientSSLServiceTests extends ESTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
ClientSSLService createClientSSLService(Settings settings) {
|
||||
private ClientSSLService createClientSSLService(Settings settings) {
|
||||
ClientSSLService clientSSLService = new ClientSSLService(settings, new Global(settings));
|
||||
clientSSLService.setEnvironment(env);
|
||||
return clientSSLService;
|
||||
|
@ -35,8 +35,8 @@ import static org.hamcrest.Matchers.sameInstance;
|
||||
|
||||
public class ServerSSLServiceTests extends ESTestCase {
|
||||
|
||||
Path testnodeStore;
|
||||
Environment env;
|
||||
private Path testnodeStore;
|
||||
private Environment env;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
|
@ -117,7 +117,7 @@ public class TransportFilterTests extends ESIntegTestCase {
|
||||
public static class InternalPlugin extends Plugin {
|
||||
@Override
|
||||
public Collection<Module> nodeModules() {
|
||||
return Collections.<Module>singletonList(new TestTransportFilterModule());
|
||||
return Collections.singletonList(new TestTransportFilterModule());
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,7 +269,7 @@ public class TransportFilterTests extends ESIntegTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
static void await(CountDownLatch latch) throws Exception {
|
||||
private static void await(CountDownLatch latch) throws Exception {
|
||||
if (!latch.await(5, TimeUnit.SECONDS)) {
|
||||
fail("waiting too long for request");
|
||||
}
|
||||
@ -298,7 +298,7 @@ public class TransportFilterTests extends ESIntegTestCase {
|
||||
|
||||
@Override
|
||||
protected Map<String, ServerTransportFilter> initializeProfileFilters() {
|
||||
return Collections.<String, ServerTransportFilter>singletonMap(TransportSettings.DEFAULT_PROFILE,
|
||||
return Collections.singletonMap(TransportSettings.DEFAULT_PROFILE,
|
||||
mock(ServerTransportFilter.NodeProfile.class));
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,12 @@
|
||||
*/
|
||||
package org.elasticsearch.xpack.security.transport.ssl;
|
||||
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.SSLContexts;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.client.Response;
|
||||
@ -18,23 +19,22 @@ import org.elasticsearch.client.transport.TransportClient;
|
||||
import org.elasticsearch.common.network.NetworkModule;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.transport.TransportAddress;
|
||||
import org.elasticsearch.test.SecurityIntegTestCase;
|
||||
import org.elasticsearch.transport.Transport;
|
||||
import org.elasticsearch.xpack.XPackPlugin;
|
||||
import org.elasticsearch.xpack.security.Security;
|
||||
import org.elasticsearch.xpack.security.ssl.ClientSSLService;
|
||||
import org.elasticsearch.xpack.security.ssl.SSLConfiguration.Global;
|
||||
import org.elasticsearch.xpack.security.transport.netty.SecurityNettyHttpServerTransport;
|
||||
import org.elasticsearch.xpack.security.transport.netty.SecurityNettyTransport;
|
||||
import org.elasticsearch.test.SecurityIntegTestCase;
|
||||
import org.elasticsearch.transport.Transport;
|
||||
import org.elasticsearch.xpack.XPackPlugin;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||
import static org.elasticsearch.test.SecuritySettingsSource.getSSLSettingsForStore;
|
||||
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
@ -60,10 +60,10 @@ public class SslClientAuthTests extends SecurityIntegTestCase {
|
||||
public void testThatHttpFailsWithoutSslClientAuth() throws IOException {
|
||||
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
|
||||
SSLContexts.createDefault(),
|
||||
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||
NoopHostnameVerifier.INSTANCE);
|
||||
|
||||
try (RestClient restClient = createRestClient(HttpClients.custom().setSSLSocketFactory(socketFactory).build(), "https")) {
|
||||
restClient.performRequest("GET", "/", Collections.emptyMap(), null);
|
||||
restClient.performRequest("GET", "/");
|
||||
fail("Expected SSLHandshakeException");
|
||||
} catch (SSLHandshakeException e) {
|
||||
assertThat(e.getMessage(), containsString("unable to find valid certification path to requested target"));
|
||||
@ -78,12 +78,12 @@ public class SslClientAuthTests extends SecurityIntegTestCase {
|
||||
|
||||
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
|
||||
sslService.sslContext(),
|
||||
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||
NoopHostnameVerifier.INSTANCE);
|
||||
|
||||
CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
|
||||
|
||||
try (RestClient restClient = createRestClient(client, "https")) {
|
||||
try (Response response = restClient.performRequest("GET", "/", Collections.emptyMap(), null,
|
||||
try (Response response = restClient.performRequest("GET", "/",
|
||||
new BasicHeader("Authorization", basicAuthHeaderValue(transportClientUsername(), transportClientPassword())))) {
|
||||
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
|
||||
assertThat(EntityUtils.toString(response.getEntity()), containsString("You Know, for Search"));
|
||||
|
@ -10,6 +10,7 @@ import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
@ -103,7 +104,7 @@ public class SslIntegrationTests extends SecurityIntegTestCase {
|
||||
CredentialsProvider provider = new BasicCredentialsProvider();
|
||||
provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(nodeClientUsername(),
|
||||
new String(nodeClientPassword().internalChars())));
|
||||
try (CloseableHttpClient client = HttpClients.custom().setSslcontext(service.sslContext())
|
||||
try (CloseableHttpClient client = HttpClients.custom().setSSLContext(service.sslContext())
|
||||
.setDefaultCredentialsProvider(provider).build();
|
||||
CloseableHttpResponse response = client.execute(new HttpGet(getNodeUrl()))) {
|
||||
assertThat(response.getStatusLine().getStatusCode(), is(200));
|
||||
@ -119,7 +120,7 @@ public class SslIntegrationTests extends SecurityIntegTestCase {
|
||||
|
||||
sslContext.init(null, factory.getTrustManagers(), new SecureRandom());
|
||||
SSLConnectionSocketFactory sf = new SSLConnectionSocketFactory(sslContext, new String[]{ "SSLv3" }, null,
|
||||
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||
NoopHostnameVerifier.INSTANCE);
|
||||
try (CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(sf).build()) {
|
||||
client.execute(new HttpGet(getNodeUrl()));
|
||||
fail("Expected a connection error due to SSLv3 not being supported by default");
|
||||
|
@ -9,10 +9,8 @@ import org.elasticsearch.client.Response;
|
||||
import org.elasticsearch.client.ResponseException;
|
||||
import org.elasticsearch.common.network.NetworkModule;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.xpack.security.authz.InternalAuthorizationService;
|
||||
import org.elasticsearch.test.SecurityIntegTestCase;
|
||||
|
||||
import java.util.Collections;
|
||||
import org.elasticsearch.xpack.security.authz.InternalAuthorizationService;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
@ -43,7 +41,7 @@ public class AnonymousUserIntegTests extends SecurityIntegTestCase {
|
||||
|
||||
public void testAnonymousViaHttp() throws Exception {
|
||||
try {
|
||||
getRestClient().performRequest("GET", "/_nodes", Collections.emptyMap(), null);
|
||||
getRestClient().performRequest("GET", "/_nodes");
|
||||
fail("request should have failed");
|
||||
} catch(ResponseException e) {
|
||||
int statusCode = e.getResponse().getStatusLine().getStatusCode();
|
||||
|
@ -41,7 +41,6 @@ import org.elasticsearch.xpack.action.XPackInfoAction;
|
||||
import org.elasticsearch.xpack.action.XPackUsageAction;
|
||||
import org.elasticsearch.xpack.common.ScriptServiceProxy;
|
||||
import org.elasticsearch.xpack.common.http.HttpClientModule;
|
||||
import org.elasticsearch.xpack.common.secret.SecretModule;
|
||||
import org.elasticsearch.xpack.common.text.TextTemplateModule;
|
||||
import org.elasticsearch.xpack.extensions.XPackExtension;
|
||||
import org.elasticsearch.xpack.extensions.XPackExtensionsService;
|
||||
@ -151,7 +150,6 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin {
|
||||
|
||||
if (transportClientMode == false) {
|
||||
modules.add(new HttpClientModule());
|
||||
modules.add(new SecretModule(settings));
|
||||
modules.add(new TextTemplateModule());
|
||||
}
|
||||
return modules;
|
||||
|
@ -5,20 +5,20 @@
|
||||
*/
|
||||
package org.elasticsearch.xpack.common.http.auth.basic;
|
||||
|
||||
import org.elasticsearch.xpack.common.http.auth.ApplicableHttpAuth;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
|
||||
import java.net.HttpURLConnection;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
import org.elasticsearch.xpack.common.http.auth.ApplicableHttpAuth;
|
||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ApplicableBasicAuth extends ApplicableHttpAuth<BasicAuth> {
|
||||
|
||||
private final String basicAuth;
|
||||
|
||||
public ApplicableBasicAuth(BasicAuth auth, SecretService service) {
|
||||
public ApplicableBasicAuth(BasicAuth auth, CryptoService service) {
|
||||
super(auth);
|
||||
basicAuth = headerValue(auth.username, auth.password.text(service));
|
||||
}
|
||||
|
@ -5,10 +5,11 @@
|
||||
*/
|
||||
package org.elasticsearch.xpack.common.http.auth.basic;
|
||||
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.xpack.common.http.auth.HttpAuthFactory;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@ -17,11 +18,11 @@ import java.io.IOException;
|
||||
*/
|
||||
public class BasicAuthFactory extends HttpAuthFactory<BasicAuth, ApplicableBasicAuth> {
|
||||
|
||||
private final SecretService secretService;
|
||||
private final CryptoService cryptoService;
|
||||
|
||||
@Inject
|
||||
public BasicAuthFactory(SecretService secretService) {
|
||||
this.secretService = secretService;
|
||||
public BasicAuthFactory(@Nullable CryptoService cryptoService) {
|
||||
this.cryptoService = cryptoService;
|
||||
}
|
||||
|
||||
public String type() {
|
||||
@ -34,6 +35,6 @@ public class BasicAuthFactory extends HttpAuthFactory<BasicAuth, ApplicableBasic
|
||||
|
||||
@Override
|
||||
public ApplicableBasicAuth createApplicable(BasicAuth auth) {
|
||||
return new ApplicableBasicAuth(auth, secretService);
|
||||
return new ApplicableBasicAuth(auth, cryptoService);
|
||||
}
|
||||
}
|
||||
|
@ -5,12 +5,13 @@
|
||||
*/
|
||||
package org.elasticsearch.xpack.common.secret;
|
||||
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -22,7 +23,10 @@ public class Secret implements ToXContent {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public char[] text(SecretService service) {
|
||||
public char[] text(CryptoService service) {
|
||||
if (service == null) {
|
||||
return text;
|
||||
}
|
||||
return service.decrypt(text);
|
||||
}
|
||||
|
||||
|
@ -1,32 +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.common.secret;
|
||||
|
||||
import org.elasticsearch.common.inject.AbstractModule;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.xpack.security.Security;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class SecretModule extends AbstractModule {
|
||||
|
||||
private final boolean securityEnabled;
|
||||
|
||||
public SecretModule(Settings settings) {
|
||||
securityEnabled = Security.enabled(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
if (securityEnabled) {
|
||||
bind(SecretService.Secure.class).asEagerSingleton();
|
||||
bind(SecretService.class).to(SecretService.Secure.class);
|
||||
} else {
|
||||
bind(SecretService.class).toInstance(SecretService.Insecure.INSTANCE);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,63 +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.common.secret;
|
||||
|
||||
import org.elasticsearch.common.component.AbstractComponent;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface SecretService {
|
||||
|
||||
char[] encrypt(char[] text);
|
||||
|
||||
char[] decrypt(char[] text);
|
||||
|
||||
class Insecure implements SecretService {
|
||||
|
||||
public static final Insecure INSTANCE = new Insecure();
|
||||
|
||||
Insecure() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] encrypt(char[] text) {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] decrypt(char[] text) {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Secure extends AbstractComponent implements SecretService {
|
||||
|
||||
private final CryptoService cryptoService;
|
||||
|
||||
@Inject
|
||||
public Secure(Settings settings, CryptoService cryptoService) {
|
||||
super(settings);
|
||||
this.cryptoService = cryptoService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] encrypt(char[] text) {
|
||||
return cryptoService.encrypt(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] decrypt(char[] text) {
|
||||
return cryptoService.decrypt(text);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,13 +5,6 @@
|
||||
*/
|
||||
package org.elasticsearch.xpack.notification.email;
|
||||
|
||||
import org.elasticsearch.SpecialPermission;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsException;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
|
||||
import javax.activation.CommandMap;
|
||||
import javax.activation.MailcapCommandMap;
|
||||
import javax.mail.MessagingException;
|
||||
@ -24,6 +17,13 @@ import java.security.PrivilegedAction;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.elasticsearch.SpecialPermission;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsException;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -62,13 +62,13 @@ public class Account {
|
||||
.build();
|
||||
|
||||
private final Config config;
|
||||
private final SecretService secretService;
|
||||
private final CryptoService cryptoService;
|
||||
private final ESLogger logger;
|
||||
private final Session session;
|
||||
|
||||
Account(Config config, SecretService secretService, ESLogger logger) {
|
||||
Account(Config config, CryptoService cryptoService, ESLogger logger) {
|
||||
this.config = config;
|
||||
this.secretService = secretService;
|
||||
this.cryptoService = cryptoService;
|
||||
this.logger = logger;
|
||||
session = config.createSession();
|
||||
}
|
||||
@ -102,7 +102,7 @@ public class Account {
|
||||
|
||||
String password = null;
|
||||
if (auth != null && auth.password() != null) {
|
||||
password = new String(auth.password().text(secretService));
|
||||
password = new String(auth.password().text(cryptoService));
|
||||
} else if (config.smtp.password != null) {
|
||||
password = new String(config.smtp.password);
|
||||
}
|
||||
|
@ -5,13 +5,13 @@
|
||||
*/
|
||||
package org.elasticsearch.xpack.notification.email;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsException;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -21,12 +21,12 @@ public class Accounts {
|
||||
private final String defaultAccountName;
|
||||
private final Map<String, Account> accounts;
|
||||
|
||||
public Accounts(Settings settings, SecretService secretService, ESLogger logger) {
|
||||
public Accounts(Settings settings, CryptoService cryptoService, ESLogger logger) {
|
||||
Settings accountsSettings = settings.getAsSettings("account");
|
||||
accounts = new HashMap<>();
|
||||
for (String name : accountsSettings.names()) {
|
||||
Account.Config config = new Account.Config(name, accountsSettings.getAsSettings(name));
|
||||
Account account = new Account(config, secretService, logger);
|
||||
Account account = new Account(config, cryptoService, logger);
|
||||
accounts.put(name, account);
|
||||
}
|
||||
|
||||
|
@ -5,32 +5,33 @@
|
||||
*/
|
||||
package org.elasticsearch.xpack.notification.email;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.Setting;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class InternalEmailService extends AbstractLifecycleComponent implements EmailService {
|
||||
|
||||
private final SecretService secretService;
|
||||
private final CryptoService cryptoService;
|
||||
public static final Setting<Settings> EMAIL_ACCOUNT_SETTING =
|
||||
Setting.groupSetting("xpack.notification.email.", Setting.Property.Dynamic, Setting.Property.NodeScope);
|
||||
|
||||
private volatile Accounts accounts;
|
||||
|
||||
@Inject
|
||||
public InternalEmailService(Settings settings, SecretService secretService, ClusterSettings clusterSettings) {
|
||||
public InternalEmailService(Settings settings, @Nullable CryptoService cryptoService, ClusterSettings clusterSettings) {
|
||||
super(settings);
|
||||
this.secretService = secretService;
|
||||
this.cryptoService = cryptoService;
|
||||
clusterSettings.addSettingsUpdateConsumer(EMAIL_ACCOUNT_SETTING, this::setEmailAccountSettings);
|
||||
setEmailAccountSettings(EMAIL_ACCOUNT_SETTING.get(settings));
|
||||
}
|
||||
@ -78,7 +79,7 @@ public class InternalEmailService extends AbstractLifecycleComponent implements
|
||||
}
|
||||
|
||||
protected Accounts createAccounts(Settings settings, ESLogger logger) {
|
||||
return new Accounts(settings, secretService, logger);
|
||||
return new Accounts(settings, cryptoService, logger);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ import org.elasticsearch.test.junit.annotations.Network;
|
||||
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
|
||||
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
|
||||
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
@ -49,15 +48,13 @@ public class HttpClientTests extends ESTestCase {
|
||||
private MockWebServer webServer;
|
||||
private HttpClient httpClient;
|
||||
private HttpAuthRegistry authRegistry;
|
||||
private SecretService secretService;
|
||||
private Environment environment = new Environment(Settings.builder().put("path.home", createTempDir()).build());
|
||||
|
||||
private int webPort;
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
secretService = SecretService.Insecure.INSTANCE;
|
||||
authRegistry = new HttpAuthRegistry(singletonMap(BasicAuth.TYPE, new BasicAuthFactory(secretService)));
|
||||
authRegistry = new HttpAuthRegistry(singletonMap(BasicAuth.TYPE, new BasicAuthFactory(null)));
|
||||
webServer = startWebServer();
|
||||
webPort = webServer.getPort();
|
||||
httpClient = new HttpClient(Settings.EMPTY, authRegistry, environment);
|
||||
|
@ -16,7 +16,6 @@ import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
|
||||
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
|
||||
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
import org.elasticsearch.xpack.common.text.TextTemplate;
|
||||
import org.elasticsearch.xpack.watcher.test.MockTextTemplateEngine;
|
||||
import org.jboss.netty.handler.codec.http.HttpHeaders;
|
||||
@ -139,7 +138,7 @@ public class HttpRequestTemplateTests extends ESTestCase {
|
||||
HttpRequestTemplate template = builder.build();
|
||||
|
||||
HttpAuthRegistry registry = new HttpAuthRegistry(singletonMap(BasicAuth.TYPE,
|
||||
new BasicAuthFactory(SecretService.Insecure.INSTANCE)));
|
||||
new BasicAuthFactory(null)));
|
||||
HttpRequestTemplate.Parser parser = new HttpRequestTemplate.Parser(registry);
|
||||
|
||||
XContentBuilder xContentBuilder = template.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS);
|
||||
|
@ -11,7 +11,6 @@ import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.xpack.notification.email.support.EmailServer;
|
||||
import org.elasticsearch.xpack.common.secret.Secret;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
@ -169,7 +168,7 @@ public class AccountTests extends ESTestCase {
|
||||
.put("smtp.port", server.port())
|
||||
.put("smtp.user", USERNAME)
|
||||
.put("smtp.password", PASSWORD)
|
||||
.build()), SecretService.Insecure.INSTANCE, logger);
|
||||
.build()), null, logger);
|
||||
|
||||
Email email = Email.builder()
|
||||
.id("_id")
|
||||
@ -206,7 +205,7 @@ public class AccountTests extends ESTestCase {
|
||||
.put("smtp.port", server.port())
|
||||
.put("smtp.user", USERNAME)
|
||||
.put("smtp.password", PASSWORD)
|
||||
.build()), SecretService.Insecure.INSTANCE, logger);
|
||||
.build()), null, logger);
|
||||
|
||||
Email email = Email.builder()
|
||||
.id("_id")
|
||||
@ -246,7 +245,7 @@ public class AccountTests extends ESTestCase {
|
||||
Account account = new Account(new Account.Config("default", Settings.builder()
|
||||
.put("smtp.host", "localhost")
|
||||
.put("smtp.port", server.port())
|
||||
.build()), SecretService.Insecure.INSTANCE, logger);
|
||||
.build()), null, logger);
|
||||
|
||||
Email email = Email.builder()
|
||||
.id("_id")
|
||||
@ -277,7 +276,7 @@ public class AccountTests extends ESTestCase {
|
||||
Account account = new Account(new Account.Config("default", Settings.builder()
|
||||
.put("smtp.host", "localhost")
|
||||
.put("smtp.port", server.port())
|
||||
.build()), SecretService.Insecure.INSTANCE, logger);
|
||||
.build()), null, logger);
|
||||
|
||||
Properties mailProperties = account.getConfig().smtp.properties;
|
||||
assertThat(mailProperties.get("mail.smtp.connectiontimeout"), is(String.valueOf(TimeValue.timeValueMinutes(2).millis())));
|
||||
@ -292,7 +291,7 @@ public class AccountTests extends ESTestCase {
|
||||
.put("smtp.connection_timeout", TimeValue.timeValueMinutes(4))
|
||||
.put("smtp.write_timeout", TimeValue.timeValueMinutes(6))
|
||||
.put("smtp.timeout", TimeValue.timeValueMinutes(8))
|
||||
.build()), SecretService.Insecure.INSTANCE, logger);
|
||||
.build()), null, logger);
|
||||
|
||||
Properties mailProperties = account.getConfig().smtp.properties;
|
||||
|
||||
@ -307,7 +306,7 @@ public class AccountTests extends ESTestCase {
|
||||
.put("smtp.host", "localhost")
|
||||
.put("smtp.port", server.port())
|
||||
.put("smtp.connection_timeout", 4000)
|
||||
.build()), SecretService.Insecure.INSTANCE, logger);
|
||||
.build()), null, logger);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ package org.elasticsearch.xpack.notification.email;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsException;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
@ -24,7 +23,7 @@ public class AccountsTests extends ESTestCase {
|
||||
.put("default_account", "account1");
|
||||
addAccountSettings("account1", builder);
|
||||
|
||||
Accounts accounts = new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
|
||||
Accounts accounts = new Accounts(builder.build(), null, logger);
|
||||
Account account = accounts.account("account1");
|
||||
assertThat(account, notNullValue());
|
||||
assertThat(account.name(), equalTo("account1"));
|
||||
@ -37,7 +36,7 @@ public class AccountsTests extends ESTestCase {
|
||||
Settings.Builder builder = Settings.builder();
|
||||
addAccountSettings("account1", builder);
|
||||
|
||||
Accounts accounts = new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
|
||||
Accounts accounts = new Accounts(builder.build(), null, logger);
|
||||
Account account = accounts.account("account1");
|
||||
assertThat(account, notNullValue());
|
||||
assertThat(account.name(), equalTo("account1"));
|
||||
@ -52,7 +51,7 @@ public class AccountsTests extends ESTestCase {
|
||||
addAccountSettings("account1", builder);
|
||||
addAccountSettings("account2", builder);
|
||||
|
||||
Accounts accounts = new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
|
||||
Accounts accounts = new Accounts(builder.build(), null, logger);
|
||||
Account account = accounts.account("account1");
|
||||
assertThat(account, notNullValue());
|
||||
assertThat(account.name(), equalTo("account1"));
|
||||
@ -70,7 +69,7 @@ public class AccountsTests extends ESTestCase {
|
||||
addAccountSettings("account1", builder);
|
||||
addAccountSettings("account2", builder);
|
||||
|
||||
Accounts accounts = new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
|
||||
Accounts accounts = new Accounts(builder.build(), null, logger);
|
||||
Account account = accounts.account("account1");
|
||||
assertThat(account, notNullValue());
|
||||
assertThat(account.name(), equalTo("account1"));
|
||||
@ -88,7 +87,7 @@ public class AccountsTests extends ESTestCase {
|
||||
addAccountSettings("account1", builder);
|
||||
addAccountSettings("account2", builder);
|
||||
try {
|
||||
new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
|
||||
new Accounts(builder.build(), null, logger);
|
||||
fail("Expected SettingsException");
|
||||
} catch (SettingsException e) {
|
||||
assertThat(e.getMessage(), is("could not find default email account [unknown]"));
|
||||
@ -97,7 +96,7 @@ public class AccountsTests extends ESTestCase {
|
||||
|
||||
public void testNoAccount() throws Exception {
|
||||
Settings.Builder builder = Settings.builder();
|
||||
Accounts accounts = new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
|
||||
Accounts accounts = new Accounts(builder.build(), null, logger);
|
||||
try {
|
||||
accounts.account(null);
|
||||
fail("no accounts are configured so trying to get the default account should throw an IllegalStateException");
|
||||
@ -110,7 +109,7 @@ public class AccountsTests extends ESTestCase {
|
||||
Settings.Builder builder = Settings.builder()
|
||||
.put("default_account", "unknown");
|
||||
try {
|
||||
new Accounts(builder.build(), SecretService.Insecure.INSTANCE, logger);
|
||||
new Accounts(builder.build(), null, logger);
|
||||
fail("Expected SettingsException");
|
||||
} catch (SettingsException e) {
|
||||
assertThat(e.getMessage(), is("could not find default email account [unknown]"));
|
||||
|
@ -8,9 +8,9 @@ package org.elasticsearch.xpack.notification.email;
|
||||
import org.elasticsearch.action.get.GetResponse;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||
import org.elasticsearch.xpack.watcher.client.WatcherClient;
|
||||
import org.elasticsearch.xpack.watcher.execution.ActionExecutionMode;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource;
|
||||
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchResponse;
|
||||
@ -34,7 +34,6 @@ import static org.elasticsearch.xpack.watcher.condition.ConditionBuilders.always
|
||||
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.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
@ -97,18 +96,10 @@ public class EmailSecretsIntegrationTests extends AbstractWatcherIntegrationTest
|
||||
assertThat(value, notNullValue());
|
||||
if (securityEnabled() && encryptSensitiveData) {
|
||||
assertThat(value, not(is((Object) PASSWORD)));
|
||||
SecretService secretService = getInstanceFromMaster(SecretService.class);
|
||||
assertThat(secretService, instanceOf(SecretService.Secure.class));
|
||||
assertThat(new String(secretService.decrypt(((String) value).toCharArray())), is(PASSWORD));
|
||||
CryptoService cryptoService = getInstanceFromMaster(CryptoService.class);
|
||||
assertThat(new String(cryptoService.decrypt(((String) value).toCharArray())), is(PASSWORD));
|
||||
} else {
|
||||
assertThat(value, is((Object) PASSWORD));
|
||||
SecretService secretService = getInstanceFromMaster(SecretService.class);
|
||||
if (securityEnabled()) {
|
||||
assertThat(secretService, instanceOf(SecretService.Secure.class));
|
||||
} else {
|
||||
assertThat(secretService, instanceOf(SecretService.Insecure.class));
|
||||
}
|
||||
assertThat(new String(secretService.decrypt(((String) value).toCharArray())), is(PASSWORD));
|
||||
}
|
||||
|
||||
// verifying the password is not returned by the GET watch API
|
||||
|
@ -10,7 +10,6 @@ import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.xpack.common.secret.Secret;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
@ -33,7 +32,7 @@ public class InternalEmailServiceTests extends ESTestCase {
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
accounts = mock(Accounts.class);
|
||||
service = new InternalEmailService(Settings.EMPTY, SecretService.Insecure.INSTANCE,
|
||||
service = new InternalEmailService(Settings.EMPTY, null,
|
||||
new ClusterSettings(Settings.EMPTY, Collections.singleton(InternalEmailService.EMAIL_ACCOUNT_SETTING))) {
|
||||
@Override
|
||||
protected Accounts createAccounts(Settings settings, ESLogger logger) {
|
||||
|
@ -11,7 +11,6 @@ import org.elasticsearch.cli.Terminal;
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
@ -123,7 +122,7 @@ public class ManualPublicSmtpServersTester {
|
||||
|
||||
static InternalEmailService startEmailService(Settings.Builder builder) {
|
||||
Settings settings = builder.build();
|
||||
InternalEmailService service = new InternalEmailService(settings, SecretService.Insecure.INSTANCE,
|
||||
InternalEmailService service = new InternalEmailService(settings, null,
|
||||
new ClusterSettings(settings, Collections.singleton(InternalEmailService.EMAIL_ACCOUNT_SETTING)));
|
||||
service.start();
|
||||
return service;
|
||||
|
@ -7,7 +7,6 @@ package org.elasticsearch.xpack.notification.email;
|
||||
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
|
||||
import javax.mail.BodyPart;
|
||||
import javax.mail.Part;
|
||||
@ -38,7 +37,7 @@ public class ProfileTests extends ESTestCase {
|
||||
.put("account.foo.smtp.host", "_host")
|
||||
.build();
|
||||
|
||||
Accounts accounts = new Accounts(settings, SecretService.Insecure.INSTANCE, logger);
|
||||
Accounts accounts = new Accounts(settings, null, logger);
|
||||
Session session = accounts.account("foo").getConfig().createSession();
|
||||
MimeMessage mimeMessage = Profile.STANDARD.toMimeMessage(email, session);
|
||||
|
||||
|
@ -17,7 +17,6 @@ import org.elasticsearch.xpack.common.http.HttpResponse;
|
||||
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
|
||||
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
|
||||
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
import org.elasticsearch.xpack.watcher.test.MockTextTemplateEngine;
|
||||
import org.junit.Before;
|
||||
|
||||
@ -42,8 +41,7 @@ public class HttpEmailAttachementParserTests extends ESTestCase {
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
SecretService.Insecure secretService = SecretService.Insecure.INSTANCE;
|
||||
HttpAuthRegistry authRegistry = new HttpAuthRegistry(singletonMap(BasicAuth.TYPE, new BasicAuthFactory(secretService)));
|
||||
HttpAuthRegistry authRegistry = new HttpAuthRegistry(singletonMap(BasicAuth.TYPE, new BasicAuthFactory(null)));
|
||||
httpRequestTemplateParser = new HttpRequestTemplate.Parser(authRegistry);
|
||||
httpClient = mock(HttpClient.class);
|
||||
|
||||
|
@ -15,17 +15,17 @@ import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.xcontent.XContentLocation;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||
import org.elasticsearch.xpack.support.clock.Clock;
|
||||
import org.elasticsearch.xpack.support.clock.SystemClock;
|
||||
import org.elasticsearch.xpack.common.secret.Secret;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
|
||||
/**
|
||||
* A xcontent parser that is used by watcher. This is a special parser that is
|
||||
* aware of watcher services. In particular, it's aware of the used {@link Clock}
|
||||
* and the {@link SecretService}. The former (clock) may be used when the current time
|
||||
* is required during the parse phase of construct. The latter (secret service) is used
|
||||
* to convert secret values (e.g. passwords, security tokens, etc..) to {@link Secret}s.
|
||||
* and the {@link CryptoService}. The former (clock) may be used when the current time
|
||||
* is required during the parse phase of construct. The latter (crypto service) is used
|
||||
* to encode secret values (e.g. passwords, security tokens, etc..) to {@link Secret}s.
|
||||
* {@link Secret}s are encrypted values that are stored in memory and are decrypted
|
||||
* on demand when needed.
|
||||
*/
|
||||
@ -35,8 +35,8 @@ public class WatcherXContentParser implements XContentParser {
|
||||
char[] chars = parser.text().toCharArray();
|
||||
if (parser instanceof WatcherXContentParser) {
|
||||
WatcherXContentParser watcherParser = (WatcherXContentParser) parser;
|
||||
if (watcherParser.secretService != null) {
|
||||
chars = watcherParser.secretService.encrypt(chars);
|
||||
if (watcherParser.cryptoService != null) {
|
||||
chars = watcherParser.cryptoService.encrypt(chars);
|
||||
}
|
||||
}
|
||||
return new Secret(chars);
|
||||
@ -50,8 +50,8 @@ public class WatcherXContentParser implements XContentParser {
|
||||
char[] chars = parser.text().toCharArray();
|
||||
if (parser instanceof WatcherXContentParser) {
|
||||
WatcherXContentParser watcherParser = (WatcherXContentParser) parser;
|
||||
if (watcherParser.secretService != null) {
|
||||
chars = watcherParser.secretService.encrypt(text.toCharArray());
|
||||
if (watcherParser.cryptoService != null) {
|
||||
chars = watcherParser.cryptoService.encrypt(text.toCharArray());
|
||||
}
|
||||
return new Secret(chars);
|
||||
}
|
||||
@ -67,12 +67,12 @@ public class WatcherXContentParser implements XContentParser {
|
||||
|
||||
private final Clock clock;
|
||||
private final XContentParser parser;
|
||||
@Nullable private final SecretService secretService;
|
||||
@Nullable private final CryptoService cryptoService;
|
||||
|
||||
public WatcherXContentParser(XContentParser parser, Clock clock, @Nullable SecretService secretService) {
|
||||
public WatcherXContentParser(XContentParser parser, Clock clock, @Nullable CryptoService cryptoService) {
|
||||
this.clock = clock;
|
||||
this.parser = parser;
|
||||
this.secretService = secretService;
|
||||
this.cryptoService = cryptoService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,7 +19,7 @@ import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.xpack.common.secret.Secret;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||
import org.elasticsearch.xpack.support.clock.Clock;
|
||||
import org.elasticsearch.xpack.support.clock.HaltedClock;
|
||||
import org.elasticsearch.xpack.watcher.Watcher;
|
||||
@ -213,7 +213,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
|
||||
private final TransformRegistry transformRegistry;
|
||||
private final ActionRegistry actionRegistry;
|
||||
private final InputRegistry inputRegistry;
|
||||
private final SecretService secretService;
|
||||
private final CryptoService cryptoService;
|
||||
private final ExecutableInput defaultInput;
|
||||
private final ExecutableCondition defaultCondition;
|
||||
private final ExecutableActions defaultActions;
|
||||
@ -222,7 +222,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
|
||||
@Inject
|
||||
public Parser(Settings settings, ConditionRegistry conditionRegistry, TriggerService triggerService,
|
||||
TransformRegistry transformRegistry, ActionRegistry actionRegistry,
|
||||
InputRegistry inputRegistry, SecretService secretService, Clock clock) {
|
||||
InputRegistry inputRegistry, @Nullable CryptoService cryptoService, Clock clock) {
|
||||
|
||||
super(settings);
|
||||
this.conditionRegistry = conditionRegistry;
|
||||
@ -230,7 +230,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
|
||||
this.triggerService = triggerService;
|
||||
this.actionRegistry = actionRegistry;
|
||||
this.inputRegistry = inputRegistry;
|
||||
this.secretService = Watcher.ENCRYPT_SENSITIVE_DATA_SETTING.get(settings) ? secretService : SecretService.Insecure.INSTANCE;
|
||||
this.cryptoService = Watcher.ENCRYPT_SENSITIVE_DATA_SETTING.get(settings) ? cryptoService : null;
|
||||
this.defaultInput = new ExecutableNoneInput(logger);
|
||||
this.defaultCondition = new ExecutableAlwaysCondition(logger);
|
||||
this.defaultActions = new ExecutableActions(Collections.emptyList());
|
||||
@ -249,10 +249,8 @@ public class Watch implements TriggerEngine.Job, ToXContent {
|
||||
* Parses the watch represented by the given source. When parsing, any sensitive data that the
|
||||
* source might contain (e.g. passwords) will be converted to {@link Secret secrets}
|
||||
* Such that the returned watch will potentially hide this sensitive data behind a "secret". A secret
|
||||
* is an abstraction around sensitive data (text). There can be different implementations of how the
|
||||
* secret holds the data, depending on the wired up {@link SecretService}. When security is enabled, a
|
||||
* {@link SecretService.Secure} is used, that potentially encrypts the data
|
||||
* using the configured system key.
|
||||
* is an abstraction around sensitive data (text). When security is enabled, the
|
||||
* {@link CryptoService} is used to encrypt the secrets.
|
||||
*
|
||||
* This method is only called once - when the user adds a new watch. From that moment on, all representations
|
||||
* of the watch in the system will be use secrets for sensitive data.
|
||||
@ -269,7 +267,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
|
||||
}
|
||||
XContentParser parser = null;
|
||||
try {
|
||||
parser = new WatcherXContentParser(createParser(source), new HaltedClock(now), withSecrets ? secretService : null);
|
||||
parser = new WatcherXContentParser(createParser(source), new HaltedClock(now), withSecrets ? cryptoService : null);
|
||||
parser.nextToken();
|
||||
return parse(id, includeStatus, parser);
|
||||
} catch (IOException ioe) {
|
||||
|
@ -68,7 +68,7 @@ public class WatcherPluginDisableTests extends ESIntegTestCase {
|
||||
public void testRestEndpoints() throws Exception {
|
||||
HttpServerTransport httpServerTransport = internalCluster().getDataNodeInstance(HttpServerTransport.class);
|
||||
try {
|
||||
getRestClient().performRequest("GET", "/_xpack/watcher", Collections.emptyMap(), null);
|
||||
getRestClient().performRequest("GET", "/_xpack/watcher");
|
||||
fail("request should have failed");
|
||||
} catch(ResponseException e) {
|
||||
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(HttpStatus.SC_BAD_REQUEST));
|
||||
|
@ -25,7 +25,6 @@ import org.elasticsearch.xpack.common.http.HttpResponse;
|
||||
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
|
||||
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
|
||||
import org.elasticsearch.xpack.common.secret.Secret;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
import org.elasticsearch.xpack.common.text.TextTemplate;
|
||||
import org.elasticsearch.xpack.common.text.TextTemplateEngine;
|
||||
import org.elasticsearch.xpack.watcher.support.xcontent.WatcherParams;
|
||||
@ -82,8 +81,7 @@ import static org.mockito.Mockito.when;
|
||||
*/
|
||||
public class EmailActionTests extends ESTestCase {
|
||||
|
||||
private SecretService secretService = mock(SecretService.class);
|
||||
private HttpAuthRegistry registry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(secretService)));
|
||||
private HttpAuthRegistry registry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(null)));
|
||||
private HttpClient httpClient = mock(HttpClient.class);
|
||||
private EmailAttachmentsParser emailAttachmentParser;
|
||||
|
||||
|
@ -28,7 +28,6 @@ import org.elasticsearch.xpack.common.http.HttpResponse;
|
||||
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
|
||||
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
|
||||
import org.elasticsearch.xpack.watcher.support.init.proxy.WatcherClientProxy;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
import org.elasticsearch.xpack.common.text.TextTemplate;
|
||||
import org.elasticsearch.xpack.common.text.TextTemplateEngine;
|
||||
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService;
|
||||
@ -87,10 +86,9 @@ public class WebhookActionTests extends ESTestCase {
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
templateEngine = new MockTextTemplateEngine();
|
||||
SecretService secretService = mock(SecretService.class);
|
||||
testBody = TextTemplate.inline(TEST_BODY_STRING).build();
|
||||
testPath = TextTemplate.inline(TEST_PATH_STRING).build();
|
||||
authRegistry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(secretService)));
|
||||
authRegistry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(null)));
|
||||
}
|
||||
|
||||
public void testExecute() throws Exception {
|
||||
|
@ -32,7 +32,6 @@ import org.elasticsearch.xpack.common.http.auth.HttpAuth;
|
||||
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
|
||||
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
|
||||
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
import org.elasticsearch.xpack.common.text.TextTemplate;
|
||||
import org.elasticsearch.xpack.common.text.TextTemplateEngine;
|
||||
import org.elasticsearch.xpack.watcher.trigger.schedule.IntervalSchedule;
|
||||
@ -71,15 +70,13 @@ import static org.mockito.Mockito.when;
|
||||
public class HttpInputTests extends ESTestCase {
|
||||
private HttpClient httpClient;
|
||||
private HttpInputFactory httpParser;
|
||||
private SecretService secretService;
|
||||
private TextTemplateEngine templateEngine;
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
httpClient = mock(HttpClient.class);
|
||||
templateEngine = mock(TextTemplateEngine.class);
|
||||
secretService = mock(SecretService.class);
|
||||
HttpAuthRegistry registry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(secretService)));
|
||||
HttpAuthRegistry registry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(null)));
|
||||
httpParser = new HttpInputFactory(Settings.EMPTY, httpClient, templateEngine, new HttpRequestTemplate.Parser(registry));
|
||||
}
|
||||
|
||||
|
@ -12,12 +12,12 @@ import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.action.get.GetResponse;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||
import org.elasticsearch.xpack.security.crypto.CryptoService;
|
||||
import org.elasticsearch.xpack.watcher.client.WatcherClient;
|
||||
import org.elasticsearch.xpack.watcher.execution.ActionExecutionMode;
|
||||
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
|
||||
import org.elasticsearch.xpack.common.http.auth.basic.ApplicableBasicAuth;
|
||||
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource;
|
||||
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
||||
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchResponse;
|
||||
@ -117,18 +117,10 @@ public class HttpSecretsIntegrationTests extends AbstractWatcherIntegrationTestC
|
||||
assertThat(value, notNullValue());
|
||||
if (securityEnabled() && encryptSensitiveData) {
|
||||
assertThat(value, not(is((Object) PASSWORD)));
|
||||
SecretService secretService = getInstanceFromMaster(SecretService.class);
|
||||
assertThat(secretService, instanceOf(SecretService.Secure.class));
|
||||
assertThat(new String(secretService.decrypt(((String) value).toCharArray())), is(PASSWORD));
|
||||
CryptoService cryptoService = getInstanceFromMaster(CryptoService.class);
|
||||
assertThat(new String(cryptoService.decrypt(((String) value).toCharArray())), is(PASSWORD));
|
||||
} else {
|
||||
assertThat(value, is((Object) PASSWORD));
|
||||
SecretService secretService = getInstanceFromMaster(SecretService.class);
|
||||
if (securityEnabled()) {
|
||||
assertThat(secretService, instanceOf(SecretService.Secure.class));
|
||||
} else {
|
||||
assertThat(secretService, instanceOf(SecretService.Insecure.class));
|
||||
}
|
||||
assertThat(new String(secretService.decrypt(((String) value).toCharArray())), is(PASSWORD));
|
||||
}
|
||||
|
||||
// verifying the password is not returned by the GET watch API
|
||||
@ -189,18 +181,10 @@ public class HttpSecretsIntegrationTests extends AbstractWatcherIntegrationTestC
|
||||
|
||||
if (securityEnabled() && encryptSensitiveData) {
|
||||
assertThat(value, not(is((Object) PASSWORD)));
|
||||
SecretService secretService = getInstanceFromMaster(SecretService.class);
|
||||
assertThat(secretService, instanceOf(SecretService.Secure.class));
|
||||
assertThat(new String(secretService.decrypt(((String) value).toCharArray())), is(PASSWORD));
|
||||
CryptoService cryptoService = getInstanceFromMaster(CryptoService.class);
|
||||
assertThat(new String(cryptoService.decrypt(((String) value).toCharArray())), is(PASSWORD));
|
||||
} else {
|
||||
assertThat(value, is((Object) PASSWORD));
|
||||
SecretService secretService = getInstanceFromMaster(SecretService.class);
|
||||
if (securityEnabled()) {
|
||||
assertThat(secretService, instanceOf(SecretService.Secure.class));
|
||||
} else {
|
||||
assertThat(secretService, instanceOf(SecretService.Insecure.class));
|
||||
}
|
||||
assertThat(new String(secretService.decrypt(((String) value).toCharArray())), is(PASSWORD));
|
||||
}
|
||||
|
||||
// verifying the password is not returned by the GET watch API
|
||||
|
@ -23,7 +23,6 @@ import org.elasticsearch.xpack.common.http.HttpMethod;
|
||||
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
|
||||
import org.elasticsearch.xpack.common.http.auth.HttpAuthRegistry;
|
||||
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuthFactory;
|
||||
import org.elasticsearch.xpack.common.secret.SecretService;
|
||||
import org.elasticsearch.xpack.common.text.TextTemplate;
|
||||
import org.elasticsearch.xpack.common.text.TextTemplateEngine;
|
||||
import org.elasticsearch.xpack.notification.email.DataAttachment;
|
||||
@ -149,7 +148,6 @@ public class WatchTests extends ESTestCase {
|
||||
private TextTemplateEngine templateEngine;
|
||||
private HtmlSanitizer htmlSanitizer;
|
||||
private HttpAuthRegistry authRegistry;
|
||||
private SecretService secretService;
|
||||
private WatcherLicensee watcherLicensee;
|
||||
private ESLogger logger;
|
||||
private Settings settings = Settings.EMPTY;
|
||||
@ -163,9 +161,8 @@ public class WatchTests extends ESTestCase {
|
||||
emailService = mock(EmailService.class);
|
||||
templateEngine = mock(TextTemplateEngine.class);
|
||||
htmlSanitizer = mock(HtmlSanitizer.class);
|
||||
secretService = mock(SecretService.class);
|
||||
watcherLicensee = mock(WatcherLicensee.class);
|
||||
authRegistry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(secretService)));
|
||||
authRegistry = new HttpAuthRegistry(singletonMap("basic", new BasicAuthFactory(null)));
|
||||
logger = Loggers.getLogger(WatchTests.class);
|
||||
searchTemplateService = mock(WatcherSearchTemplateService.class);
|
||||
}
|
||||
@ -181,7 +178,6 @@ public class WatchTests extends ESTestCase {
|
||||
ScheduleRegistry scheduleRegistry = registry(schedule);
|
||||
TriggerEngine triggerEngine = new ParseOnlyScheduleTriggerEngine(Settings.EMPTY, scheduleRegistry, clock);
|
||||
TriggerService triggerService = new TriggerService(Settings.EMPTY, singleton(triggerEngine));
|
||||
SecretService secretService = SecretService.Insecure.INSTANCE;
|
||||
|
||||
ExecutableInput input = randomInput();
|
||||
InputRegistry inputRegistry = registry(input);
|
||||
@ -209,7 +205,7 @@ public class WatchTests extends ESTestCase {
|
||||
BytesReference bytes = XContentFactory.jsonBuilder().value(watch).bytes();
|
||||
logger.info("{}", bytes.utf8ToString());
|
||||
Watch.Parser watchParser = new Watch.Parser(settings, conditionRegistry, triggerService, transformRegistry, actionRegistry,
|
||||
inputRegistry, secretService, clock);
|
||||
inputRegistry, null, clock);
|
||||
|
||||
Watch parsedWatch = watchParser.parse("_name", includeStatus, bytes);
|
||||
|
||||
@ -231,7 +227,6 @@ public class WatchTests extends ESTestCase {
|
||||
ScheduleRegistry scheduleRegistry = registry(randomSchedule());
|
||||
TriggerEngine triggerEngine = new ParseOnlyScheduleTriggerEngine(Settings.EMPTY, scheduleRegistry, clock);
|
||||
TriggerService triggerService = new TriggerService(Settings.EMPTY, singleton(triggerEngine));
|
||||
SecretService secretService = SecretService.Insecure.INSTANCE;
|
||||
ExecutableCondition condition = randomCondition();
|
||||
ConditionRegistry conditionRegistry = registry(condition);
|
||||
ExecutableInput input = randomInput();
|
||||
@ -248,7 +243,7 @@ public class WatchTests extends ESTestCase {
|
||||
.startArray("actions").endArray()
|
||||
.endObject();
|
||||
Watch.Parser watchParser = new Watch.Parser(settings, conditionRegistry, triggerService, transformRegistry, actionRegistry,
|
||||
inputRegistry, secretService, clock);
|
||||
inputRegistry, null, clock);
|
||||
try {
|
||||
watchParser.parse("failure", false, jsonBuilder.bytes());
|
||||
fail("This watch should fail to parse as actions is an array");
|
||||
@ -262,7 +257,6 @@ public class WatchTests extends ESTestCase {
|
||||
ScheduleRegistry scheduleRegistry = registry(schedule);
|
||||
TriggerEngine triggerEngine = new ParseOnlyScheduleTriggerEngine(Settings.EMPTY, scheduleRegistry, SystemClock.INSTANCE);
|
||||
TriggerService triggerService = new TriggerService(Settings.EMPTY, singleton(triggerEngine));
|
||||
SecretService secretService = SecretService.Insecure.INSTANCE;
|
||||
|
||||
ConditionRegistry conditionRegistry = registry(new ExecutableAlwaysCondition(logger));
|
||||
InputRegistry inputRegistry = registry(new ExecutableNoneInput(logger));
|
||||
@ -277,7 +271,7 @@ public class WatchTests extends ESTestCase {
|
||||
.endObject();
|
||||
builder.endObject();
|
||||
Watch.Parser watchParser = new Watch.Parser(settings, conditionRegistry, triggerService, transformRegistry, actionRegistry,
|
||||
inputRegistry, secretService, SystemClock.INSTANCE);
|
||||
inputRegistry, null, SystemClock.INSTANCE);
|
||||
Watch watch = watchParser.parse("failure", false, builder.bytes());
|
||||
assertThat(watch, notNullValue());
|
||||
assertThat(watch.trigger(), instanceOf(ScheduleTrigger.class));
|
||||
|
@ -10,7 +10,8 @@
|
||||
wait_for_status: yellow
|
||||
|
||||
|
||||
- do: {xpack.watcher.stats:{}}
|
||||
- do:
|
||||
xpack.watcher.stats: {}
|
||||
- match: { "watcher_state": "started" }
|
||||
- match: { "watch_count": 0 }
|
||||
|
||||
@ -93,7 +94,8 @@
|
||||
- do:
|
||||
indices.refresh: {}
|
||||
|
||||
- do: {xpack.watcher.stats:{}}
|
||||
- do:
|
||||
xpack.watcher.stats: {}
|
||||
- match: { "watch_count": 1 }
|
||||
|
||||
# Simulate a Thread.sleep()
|
||||
@ -142,5 +144,6 @@
|
||||
- match: { found: true }
|
||||
|
||||
|
||||
- do: {xpack.watcher.stats:{}}
|
||||
- do:
|
||||
xpack.watcher.stats: {}
|
||||
- match: { "watch_count": 0 }
|
||||
|
@ -1,13 +1,22 @@
|
||||
---
|
||||
"Test get watch api":
|
||||
setup:
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
---
|
||||
teardown:
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
id: "my_watch"
|
||||
ignore: 404
|
||||
|
||||
---
|
||||
"Test get watch api":
|
||||
- do:
|
||||
xpack.watcher.put_watch:
|
||||
id: "my_watch"
|
||||
body: >
|
||||
body: >
|
||||
{
|
||||
"trigger": {
|
||||
"schedule": {
|
||||
@ -43,5 +52,5 @@
|
||||
id: "my_watch"
|
||||
- match: { found : true}
|
||||
- match: { _id: "my_watch" }
|
||||
- match: { _status.version: 1 }
|
||||
- is_true: _status.version
|
||||
- is_false: watch.status
|
||||
|
@ -1,18 +1,27 @@
|
||||
---
|
||||
setup:
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
---
|
||||
teardown:
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
id: "cluster_health_watch"
|
||||
ignore: 404
|
||||
|
||||
---
|
||||
"Getting started - Monitor cluster health":
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
|
||||
- do: {xpack.watcher.stats:{}}
|
||||
xpack.watcher.stats: {}
|
||||
- match: { "watcher_state": "started" }
|
||||
- match: { "watch_count": 0 }
|
||||
|
||||
- do:
|
||||
xpack.watcher.put_watch:
|
||||
id: "cluster_health_watch"
|
||||
body: >
|
||||
body: >
|
||||
{
|
||||
"trigger": {
|
||||
"schedule": {
|
||||
@ -52,7 +61,8 @@
|
||||
- match: { _id: "cluster_health_watch" }
|
||||
- match: { created: true }
|
||||
|
||||
- do: {xpack.watcher.stats:{}}
|
||||
- do:
|
||||
xpack.watcher.stats: {}
|
||||
- match: { "watch_count": 1 }
|
||||
|
||||
# Simulate a Thread.sleep()
|
||||
@ -101,5 +111,6 @@
|
||||
- match: { found: true }
|
||||
|
||||
|
||||
- do: {xpack.watcher.stats:{}}
|
||||
- do:
|
||||
xpack.watcher.stats: {}
|
||||
- match: { "watch_count": 0 }
|
||||
|
@ -1,9 +1,18 @@
|
||||
---
|
||||
"Test put watch api with watch level throttle":
|
||||
setup:
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
wait_for_status: yellow
|
||||
|
||||
---
|
||||
teardown:
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
id: "my_watch1"
|
||||
ignore: 404
|
||||
|
||||
---
|
||||
"Test put watch api with watch level throttle":
|
||||
- do:
|
||||
xpack.watcher.put_watch:
|
||||
id: "my_watch1"
|
||||
|
@ -1,9 +1,18 @@
|
||||
---
|
||||
"Test put watch api with action level throttle period":
|
||||
setup:
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
wait_for_status: yellow
|
||||
|
||||
---
|
||||
teardown:
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
id: "my_watch1"
|
||||
ignore: 404
|
||||
|
||||
---
|
||||
"Test put watch api with action level throttle period":
|
||||
- do:
|
||||
xpack.watcher.put_watch:
|
||||
id: "my_watch1"
|
||||
|
@ -1,15 +1,24 @@
|
||||
---
|
||||
"Test put inactive watch":
|
||||
setup:
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
---
|
||||
teardown:
|
||||
- do:
|
||||
xpack.watcher.delete_watch:
|
||||
id: "my_watch"
|
||||
ignore: 404
|
||||
|
||||
---
|
||||
"Test put inactive watch":
|
||||
- do:
|
||||
xpack.watcher.put_watch:
|
||||
id: "my_watch"
|
||||
master_timeout: "40s"
|
||||
active: false
|
||||
body: >
|
||||
body: >
|
||||
{
|
||||
"trigger": {
|
||||
"schedule": {
|
||||
@ -45,5 +54,4 @@
|
||||
|
||||
- match: { found : true }
|
||||
- match: { _id: "my_watch" }
|
||||
- match: { _status.version: 1 }
|
||||
- match: { _status.state.active: false }
|
||||
|
Loading…
x
Reference in New Issue
Block a user