-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Add an elasticsearch scaler based on search template #2304
Add an elasticsearch scaler based on search template #2304
Conversation
Signed-off-by: Nicolas L <nicolas.lassalle@zenika.com>
Thanks for the PR! Would you mind adding a new changelog entry please? |
Signed-off-by: Nicolas L <nicolas.lassalle@zenika.com>
Signed-off-by: Nicolas L <nicolas.lassalle@zenika.com>
the changelog is in progress. Ive opened the PR with a wrong github account. Would you be OK if I reopen it with the proper github account? |
Signed-off-by: Nicolas L <nicolas.lassalle@zenika.com>
Signed-off-by: Nicolas L <nicolas.lassalle@zenika.com>
Signed-off-by: Nicolas L <nicolas.lassalle@zenika.com>
Signed-off-by: Nicolas L <nicolas.lassalle@zenika.com>
Signed-off-by: Nicolas L <nicolas.lassalle@zenika.com>
Signed-off-by: Nicolas L <nicolas.lassalle@zenika.com>
Signed-off-by: Nicolas L <nicolas.lassalle@zenika.com>
Signed-off-by: Nicolas L <nicolas.lassalle@zenika.com>
Signed-off-by: Nicolas L <nicolas.lassalle@zenika.com>
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.
Hi,
In general looks good, only some small changes :)
Thanks a ton for your contribution ❤️
pkg/scalers/elasticsearch_scaler.go
Outdated
if val, ok := config.TriggerMetadata["unsafeSsl"]; ok { | ||
meta.unsafeSsl, err = strconv.ParseBool(val) | ||
if err != nil { | ||
return nil, fmt.Errorf("error parsing unsafeSsL: %s", err) |
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.
return nil, fmt.Errorf("error parsing unsafeSsL: %s", err) | |
return nil, fmt.Errorf("error parsing unsafeSsl: %s", err) |
Does the last L need to be in capital letter?
pkg/scalers/elasticsearch_scaler.go
Outdated
if meta.unsafeSsl { | ||
tr := &http.Transport{ | ||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, | ||
} | ||
config.Transport = tr | ||
} |
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'm not an expert in elastic and maybe it's not possible but, could we avoid the if block using something like this?
if meta.unsafeSsl { | |
tr := &http.Transport{ | |
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, | |
} | |
config.Transport = tr | |
} | |
config.Transport = &http.Transport{ | |
TLSClientConfig: &tls.Config{InsecureSkipVerify: meta.unsafeSsl}, | |
} |
We are using that approach inside utils package for the HTTPClient
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.
make senses. I dig further to check
// Run the templated search | ||
res, err := s.esClient.SearchTemplate( | ||
&body, | ||
s.esClient.SearchTemplate.WithIndex(s.metadata.indexes...), |
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 should pass the context until here because you could add .WithContext
. With this change, the request context can be managed from outside the scaler.
pkg/scalers/elasticsearch_scaler.go
Outdated
|
||
externalMetric := &v2beta2.ExternalMetricSource{ | ||
Metric: v2beta2.MetricIdentifier{ | ||
Name: GenerateMetricNameWithIndex(s.metadata.targetValue, metricName), |
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 name should be generated using the ScalerIndex and the "metricName". The ScalerIndex is a parameter that all scalers receive in the constructor and which should be propagated to here in order to avoid conflicts. Also, it'd be tested during the unit test to ensure that it's correctly propagated.
This point is explained more in depth here.
All the other scalers propagate it, so you can check any other :)
/run-e2e elasticsearch* |
tests/scalers/elasticsearch.test.ts
Outdated
fs.writeFileSync(elasticsearchTmpFile.name, elasticsearchStatefulsetYaml.replace('{{ELASTIC_PASSWORD}}', elasticPassword)) | ||
|
||
t.is(0, sh.exec(`kubectl apply --namespace ${elasticsearchNamespace} -f ${elasticsearchTmpFile.name}`).code, 'creating an elasticsearch statefulset should work.') | ||
t.is(0, waitForRollout('statefulset', "elasticsearch", elasticsearchNamespace)) |
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 e2e tests are failing because this could need a bit more time. WDYT?
t.is(0, waitForRollout('statefulset', "elasticsearch", elasticsearchNamespace)) | |
t.is(0, waitForRollout('statefulset', "elasticsearch", elasticsearchNamespace, 300)) |
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.
the elasticsearch image is huge (~1.2GB) and on my 6 cores laptop it takes ~20-30 seconds to start.
Let's check with 300 iterations
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 will run again e2e tests when you increase the waiting timeout :)
Signed-off-by: Nicolas L <nicolas.lassalle@zenika.com>
could you let me know about this question? I really would like that the PR is attached to my proper GH account 🙏 |
Small changes are pushed. My pleasure, I had a great time coding on keda! |
I think that it's not a problem, go 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.
Hi,
another small nits:
Could you review the comment about the metric name and add atl least 1 test with ScalerIndex > 0?
Thanks! ❤️
|
||
externalMetric := &v2beta2.ExternalMetricSource{ | ||
Metric: v2beta2.MetricIdentifier{ | ||
Name: GenerateMetricNameWithIndex(s.metadata.targetValue, metricName), | ||
Name: GenerateMetricNameWithIndex(s.metadata.targetValue, s.metadata.metricName), |
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 should call only once to GenerateMetricNameWithIndex
. This index is not related with any inside the scaler, it's related with the trigger index inside the ScaledObject to avoid conflicts with duplicated names in the same ScaledObject.
You could call to the function here or in the constructor like you are doing but don't do it both, because the final metric name with current code will be like s{s.metadata.targetValue}-s{config.ScalerIndex}-elasticsearch-%s
. It should be like s{config.ScalerIndex}-elasticsearch-%s
/run-e2e elasticsearch* |
Duplicate of #2311 |
I have commented again on the new PR, you can ignore this :) |
thanks a lot :) |
Signed-off-by: Nicolas L nicolas.lassalle@zenika.com
I am pleased to propose you the implementation of an Elasticsearch scaler based on a search template. Using a search template make things easy on the scaler configuration. The user must provide a search template name and eventually its params. The search result can be parsed using the gjson library like the metrics api scaler does.
For now, the authentication is based on username/password ; on the future we could imagine provide a CA certificate to validate a self signed certificate or ECE credentials.
I had a great time working on this scaler and I would be very pleased to get your code review's feedback.
Checklist
Fixes #1756