-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Enable Product check from @elastic/elasticsearch-js #107663
Enable Product check from @elastic/elasticsearch-js #107663
Conversation
1b6bb04
to
fa3d76f
Compare
fa3d76f
to
0e21c2c
Compare
Blocked by #107536 |
0e21c2c
to
02a9a4b
Compare
02a9a4b
to
c9ccff1
Compare
Pinging @elastic/kibana-core (Team:Core) |
Pinging @elastic/kibana-operations (Team:Operations) |
@@ -55,3 +63,67 @@ describe('elasticsearch clients', () => { | |||
expect(resp.headers!.warning).toMatch('system indices'); | |||
}); | |||
}); | |||
|
|||
function createFakeElasticsearchServer() { |
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 I can see we rely on a product check to be performed during Elasticsearch version compatibility check
step. Do you think it might make sense to have an explicit product check
step during setup
?
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.
AFAIK, you cannot force a product check. The only thing that you can do is to make a random request (other than GET /
), and the client will run it internally.
That said, I agree that we could run GET /_nodes
like we do in the version-check polling, as the first thing during startup, and even crash Kibana if we agree to do so in the discussion #107663 (comment)
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.
Implemented the method isValidConnection
.
await kibanaServer.preboot(); | ||
await kibanaServer.setup(); | ||
kibanaServer.start(); | ||
await fakeServer.firstRequestReceived$.pipe(first()).toPromise(); // Waiting for the first ES request instead of the start to complete, because start can't never complete due to waiting for ES to be ready |
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.
So Kibana doesn't stop, but running indefinitely until the problem is resolved? Is it okay from the product point of view? IMO it's okay since a normal ES server might start later, just want to confirm it aligns with the product vision @thesmallestduck
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.
To be fair, AFAIK, once the client marks the connection as Product-invalid, it internally never checks again. It means that even when the ES server goes back to normal.
It might make sense to crash Kibana because of that. Although, we might need a retry logic to handle any possible errors other than the product check.
As an additional thought: we don't stop when Kibana's credentials or the ES host config are wrong.
I wonder if we should discuss this "Crash during startup on specific ES config errors" on a follow-up issue 🤔
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 just noticed about this sentence in the original issue:
Kibana should handle the incompatibility check exception thrown by @elastic/elasticsearch to log an error and stop Kibana gracefully.
I'll implement the shutdown logic 👍
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.
@afharo I added this requirement, but I didn't discuss it with the product management. Let's wait for @thesmallestduck feedback
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.
Agree with @mshustov , a shutdown with a log message seems preferable to me. It is important to give an indication of why Kibana isn't functioning. An indefinite hang without a log message when connecting to an incorrect ES version seems unpleasant.
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.
Deal! I'll trigger Kibana's shutdown when we see the ProductCheckError. FYI, we already log the error. But I'll make sure that it's more explicit.
// eslint-disable-next-line | ||
const resp = await supertest(kibanaServer['server']['http']['prebootServer']['server']!.listener) // Mind that we are using the prebootServer at this point because the migration gets hanging, while waiting for ES to be correct | ||
.get('/api/status') | ||
.expect(503); |
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.
It's turned out you cannot test it locally in the dev
mode since basePathProxy
blocks all the calls to the http
preboot server 😞
if (msg === 'SERVER_LISTENING') { |
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.
Hum, this case is supposed to be handled by
kibana/src/core/server/bootstrap.ts
Lines 88 to 91 in 237256a
const isSetupOnHold = preboot.isSetupOnHold(); | |
if (process.send && isSetupOnHold) { | |
process.send(['SERVER_LISTENING']); | |
} |
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.
Hum, this case is supposed to be handled by
@pgayvallet Right now, this condition is always false
because no plugins call holdSetupUntilResolved
.
return send( | ||
200, | ||
{ | ||
name: 'es-bin', |
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.
why didn't this test contain this object before?
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.
es_bin
was not covering the GET /
requests. It'd just returned 404 because of the default use case. This means, that the client would never pass the Product Check and all the kbn-es
tests would fail.
We can either disable the product check for these tests, or handle the specific request to pass it and unblock the client from that state.
…t-product-check-behaviour
Fixed them with |
docs/development/core/server/kibana-plugin-core-server.elasticsearchconfig.md
Outdated
Show resolved
Hide resolved
root = kbnTestServer.createRoot({ | ||
migrations: { skip: true }, | ||
plugins: { initialize: false }, | ||
elasticsearch: { skipStartupConnectionCheck: true }, |
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 don't fancy adding another config value just for testing but mock the service might over-complicate the testing and diverge from the production setup even more.
@afharo Would you mind tagging config values used for testing purposes? It might help us to get rid of them in the future. Maybe we should allow using them in the dev
mode only? (if they aren't used in functional tests which are run in production
mode)
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.
Done! I had to do it only when running from source (dist === false
) because integration tests run with dev: false
.
@jbudz FYI: I removed the config from kibana-docker
because it is now only allowed when running from source.
// and this config is solely introduced to allow some of the integration tests to run without an ES server. | ||
schema.contextRef('dist'), | ||
true, | ||
schema.boolean({ |
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: you can use schena.never()
instead
kibana/src/plugins/maps_ems/config.ts
Lines 70 to 75 in 011955f
emsUrl: schema.conditional( | |
schema.siblingRef('proxyElasticMapsServiceInMaps'), | |
true, | |
schema.never(), | |
schema.string({ defaultValue: '' }) | |
), |
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.
makes sense! but then the types will be skipStartupConnectionCheck?: boolean
, meaning that we'll have undefined | false | true
, it doesn't change much of the behaviour/logic, but do we want those 3 states?
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.
no, we don't. We can normalize them in ElasticsearchConfig
:
this.skipStartupConnectionCheck = Boolean(rawConfig.skipStartupConnectionCheck)
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 it! The error message is not as self-explanatory, though:
"[skipStartupConnectionCheck]: a value wasn't expected to be present"
as opposed to the current
"[skipStartupConnectionCheck]: \"skipStartupConnectionCheck\" can only be set to true when running from source to allow integration tests to run without an ES server"
If you think it's fine, I'm happy to change to schema.never()
:)
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.
If you think it's fine, I'm happy to change to
Up to you
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'll leave it as is for now then, for consistency with other keys in the same Elasticsearch config (i.e.: ignoreVersionMismatch
).
I've created #110239 to follow up and change them all if we think schema.never()
is a better approach.
💚 Build Succeeded
Metrics [docs]
History
To update your PR or re-run it, just comment with: |
Co-authored-by: Kibana Machine <[email protected]>
💚 Backport successful
This backport PR will be merged automatically after passing CI. |
Co-authored-by: Kibana Machine <[email protected]> Co-authored-by: Alejandro Fernández Haro <[email protected]>
Summary
Resolves #105557.
In #107642 we disabled the Product Check while we made sure Kibana was ready for it (and solved some bugs we noticed in the Product-Check implementation). This PR enables the feature back and adds tests to confirm that the new Product check from
@elastic/elasticsearch-js
does not break Kibana's behaviour.Checklist
For maintainers