-
Notifications
You must be signed in to change notification settings - Fork 730
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Verify connection to Elasticsearch #1487
Conversation
Kibana implements a periodical version check as well https://github.com/elastic/kibana/blob/ef6b84dfa544a4677e1a33e911ef484979b5af17/src/core/server/elasticsearch/version_check/ensure_es_version.ts#L142 but both checks complement each other.
I guess we need to handle the incompatibility error in a special way to stop the Kibana instance. It might require additional work on the Kibana side to trigger |
@mshustov the check will be shipped in v7. |
@delvedor in which version? I will fill out an ER for the Kibana. |
index.js
Outdated
// sync product check | ||
const tSymbols = Object.getOwnPropertySymbols(this.transport) | ||
client.transport[tSymbols[0]] = this.transport[tSymbols[0]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems a bit fragile IMO to rely on the order of when the symbols were assigned outside the Transport
class. Would it make sense to add a function like this.transport.sync(client.transport)
so that the order of the symbols does not need to be relied on?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call out, I'll see what I can do.
if (err) { | ||
if (err.statusCode === 401 || err.statusCode === 403) { | ||
this[kProductCheck] = 2 | ||
process.emitWarning('The client is unable to verify that the server is Elasticsearch due to security privileges on the server side. Some functionality may not be compatible if the server is running an unsupported product.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think this wording would be more clear
process.emitWarning('The client is unable to verify that the server is Elasticsearch due to security privileges on the server side. Some functionality may not be compatible if the server is running an unsupported product.') | |
process.emitWarning('The client is unable to verify that the server is Elasticsearch due to an authentication error with the server. Some functionality may not be compatible if the server is running an unsupported product.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like your suggestion, but this message cannot be changed as it has already been approved by product :)
@@ -494,6 +536,51 @@ class Transport { | |||
callback(null, hosts) | |||
}) | |||
} | |||
|
|||
productCheck () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add any debug logging to this check so that we can easily find problems with it if it's not working as intended? Specifically, it'd be helpful to be able to inspect the response from Elasticsearch and know which branch failed the check.
productCheckEmitter.emit('product-check', false) | ||
} | ||
} else { | ||
if (result.body.version == null || typeof result.body.version.number !== 'string') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO I'd rather not rely on loose equality between undefined
and null
and would add an explicit check here. If nothing else, this makes it clear that this case should be tested.
if (result.body.version == null || typeof result.body.version.number !== 'string') { | |
if (result.body.version === null || result.body.version === undefined || typeof result.body.version.number !== 'string') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I know, when you are checking for both null
and undefined
, doing == null
does the job pretty well, as it's testing for both.
cluster_name: 'docker-cluster', | ||
cluster_uuid: 'cQ5pAMvRRTyEzObH4L5mTA', | ||
version: { | ||
number: '8.0.0-SNAPSHOT', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Should we be using SNAPSHOT
in the test data? (applies to all of these tests)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that we are only looking for the first two numbers it's fine :)
lucene_version: '8.9.0', | ||
minimum_wire_compatibility_version: '7.15.0', | ||
minimum_index_compatibility_version: '7.0.0' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I don't think these are correct for any of the 7.x/6.x/5.x/4.x tests. They're not being used by the check right now, but it seems worth making sure this tests data is close to being accurate in case we do use these fields in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, I only changed the fields that we need to validate.
Given that from 7.14 we'll only test the response headers there is no need to make this too much future proof. I'll revisit if needed :)
const MockConnection = buildMockConnection({ | ||
onRequest (params) { | ||
return { | ||
statusCode: 401, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add test for 403 case for full coverage
This reverts commit 17c744e
return productCheckEmitter.emit('product-check', false) | ||
} | ||
} else if (major === 7 && minor < 14) { | ||
if (tagline !== 'You Know, for Search' || result.body.version.build_flavor !== 'default') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI this breaks support for the oss docker images <= 7.10.1.
The build_flavor in there s oss
.
{
"name" : "elasticsearch-production-2",
"cluster_name" : "elasticsearch-bmg-prd",
"cluster_uuid" : "41tljEp7T66B-13N2zaE4A",
"version" : {
"number" : "7.10.1",
"build_flavor" : "oss",
"build_type" : "docker",
"build_hash" : "1c34507e66d7db1211f66f3513706fdf548736aa",
"build_date" : "2020-12-05T01:00:33.671820Z",
"build_snapshot" : false,
"lucene_version" : "8.7.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
While an upgrade to a newer image fixes the incompatibility, you might want to adopt the check in here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello! Please see #1519.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Thomas, that's then on purpose as I've assumed. There's just no mention in this PR, which could have the change a bit more transparent.
Follows this logic for verifying a connection to Elasticsearch:
Before the first API request:
/
, inspect the response:/
fails with401
or403
pass the check and show a warning (message will be linked later). This happens if themonitor
permission missing for user. The subsequent checks must be ignored.version
field or if theversion
field value is <6.0.0 raise an error.version
field and it's >= 6.0.0 and <7.0.0:tagline
field or if thetagline
field value isn'tYou know, for Search
raise an error.version
field and it's >=7.0.0 and <7.14.0:tagline
field or if thetagline
field value isn'tYou know, for Search
raise an error.build_flavor
field or if thebuild_flavor
field value isn'tdefault
raise an error.version
field and it's >=7.14.0:X-Elastic-Product
HTTP header in the response or if theX-Elastic-Product
HTTP header value isn'tElasticsearch
raise an error.