-
Notifications
You must be signed in to change notification settings - Fork 1.9k
[kibana] create a secret with es token #1720
Conversation
9861c77
to
4a590d9
Compare
4a590d9
to
827ddb3
Compare
👋🏻 @jbudz @pugnascotia the Node JS script is working fine but could surely be optimized, advises are welcome. I'm also looking for a better way to handle the case where the Elasticsearch token doesn't exist yet by not having to consider that HTTP 404 is successful (TLDR, when trying to delete an ES token that doesn't exist, it's returning 404) if you have some better idea. |
During the upgrade tests, I think that ES cluster isn't completely ready when kibana is upgraded. Indeed Node JS logs are showing
However, the K8S job is still in successful state. Need to find a way to fail the JS script in case of this error:
|
source $HOME/.elasticsearch-serviceaccounttoken | ||
// Elasticsearch API | ||
const esPath = '_security/service/elastic/kibana/credential/token/{{ template "kibana.fullname" . }}'; | ||
const esUrl = '{{ .Values.elasticsearchHosts }}' + '/' + esPath |
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.
Will .Values.elasticsearchHosts
always only have a single value?
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 question, it seems it was supposed to support multiple values but a bug that was never fixed prevented it (#603).
As this Kibana chart is supposed to connect to an Elasticsearch cluster deployed via the Elastic Helm charts, all Elasticsearch pods are supposed to be available via a single K8S service that should be used in .Values.elasticsearchHosts
.
IMHO, It's not worth fixing #603 and making the script compatible with multiple URLs. I'll update the doc to mention that a single URL (Elasticsearch service URL) is expected for this value, to make it clear.
switch (command) { | ||
case 'create': | ||
console.log('Creating a new Elasticsearch token for Kibana') | ||
createEsToken(); |
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 think it would be cleaner to always return the promises created by requestPromise
, so that they are chained together, and put a single top-level .catch(...)
here that logs any errors. If that isn't clear, I can put the suggested changes in a rustpad.
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.
Do you mean something like that?
function createEsToken() {
// Chaining requests
console.log('Cleaning previous token');
return requestPromise(esUrl, esTokenDeleteOptions).then(() => {
console.log('Creating new token');
requestPromise(esUrl, esTokenCreateOptions).then(response => {
// ...
requestPromise(k8sPostSecretUrl, secretCreateOptions, secretData)
});
});
}
function cleanEsToken() {
// Chaining requests
console.log('Cleaning token');
return requestPromise(esUrl, esTokenDeleteOptions).then(() => {
// Create the k8s secret
console.log('Delete K8S secret');
requestPromise(k8sDeleteSecretUrl, secretDeleteOptions)
});
}
const command = process.argv[2];
switch (command) {
case 'create':
console.log('Creating a new Elasticsearch token for Kibana')
createEsToken().catch(err => {
console.error(err);
});
break;
case 'clean':
console.log('Cleaning the Kibana Elasticsearch token')
cleanEsToken().catch(err => {
console.error(err);
});
break;
default:
console.log('Unknown command');
}
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.
Yes, just make sure you're always returning the value of requestPromise
, and the chain of promises will finally resolve in the switch
.
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 in e3ef0c1
Co-authored-by: Rory Hunter <pugnascotia@users.noreply.github.com>
improved in 43c08a1 |
@pugnascotia PTAL 🙏🏻 |
I could reproduce it by setting Elasticsearch replicas to 0 and running the script manually: kibana@pre-install-kb-kibana-wh4lm:~$ node/bin/node helm-scripts/manage-es-token.js create
Creating a new Elasticsearch token for Kibana
Cleaning previous token
DELETE undefined failed: connect ECONNREFUSED 10.44.6.135:9200
Error: connect ECONNREFUSED 10.44.6.135:9200
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1187:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '10.44.6.135',
port: 9200
}
kibana@pre-install-kb-kibana-wh4lm:~$ echo $?
0 Despite logging the Need to ensure that the script returns a different RC when it is failing with this error. |
should be fixed by 86386f0 |
Co-authored-by: Rory Hunter <pugnascotia@users.noreply.github.com>
Co-authored-by: Rory Hunter <pugnascotia@users.noreply.github.com>
ok to test |
https://devops-ci.elastic.co/job/elastic+helm-charts+pull-request+integration-filebeat/1343/FILEBEAT_SUITE=default,KUBERNETES_VERSION=1.24,label=ubuntu/ is a known transient issue, just waiting for a few more review to merge. |
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.
Great job!! LGTM
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.
LGTM 👍
const base64Token = Buffer.from(token, 'utf8').toString('base64'); | ||
|
||
// Prepare the k8s secret | ||
secretData = JSON.stringify({ |
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.
secretData = JSON.stringify({ | |
const secretData = JSON.stringify({ |
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.
whoops I missed the merge, didn't refresh in time. Sorry about the confusion.
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 follow up with a PR)
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.
This PR moves the Elasticsearch token for Kibana creation into Helm pre-install hooks and adds it to a K8S secret so it can be used by every pod of the Kibana Deployment.
The K8S secret and all linked resources are cleaned in post-delete hooks.
The call to Elasticsearch and K8S API to create the ES token and convert it to a secret are done in a Node JS script because the only language runtime available in the Kibana Docker image are Node and Bash, but
jq
command isn't available which exclude Bash script.The Node JS script is also available in plain JS format to facilitate the review: https://gist.github.com/jmlrt/482b3d984588c1d3e10a84ce5fcd7b3b
Many thanks @pugnascotia for the help on this script 🙏🏻
Follow-up of #1679
Replace #1715
Fixes #1714