-
Notifications
You must be signed in to change notification settings - Fork 18
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
OpenSearch: Add config button to detect opensearch version #153
Conversation
Backend code coverage report for PR #153 |
Frontend code coverage report for PR #153
|
Levitate is-compatible report: 🔍 Resolving @grafana/data@latest... 🔬 Checking compatibility between ./src/module.ts and @grafana/data@9.5.1... 🔬 Checking compatibility between ./src/module.ts and @grafana/ui@9.5.1... 🔬 Checking compatibility between ./src/module.ts and @grafana/runtime@9.5.1... 🔬 Checking compatibility between ./src/module.ts and @grafana/e2e-selectors@9.5.1... ✔️ ./src/module.ts appears to be compatible with @grafana/data,@grafana/ui,@grafana/runtime,@grafana/e2e-selectors |
@@ -0,0 +1,50 @@ | |||
import { DataSourceInstanceSettings, DataSourcePluginMeta, PluginMetaInfo, PluginType } from '@grafana/data'; |
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.
Maybe excessive? But I figured we might get use out of it in the future.
@@ -2,7 +2,9 @@ import { DataSourceSettings } from '@grafana/data'; | |||
import { Flavor, OpenSearchOptions } from '../types'; | |||
import { createDatasourceSettings } from '../dependencies/mocks'; | |||
|
|||
export function createDefaultConfigOptions(): DataSourceSettings<OpenSearchOptions> { |
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.
Moved this file for neatness
message: 'OpenSearch error: ' + message, | ||
error: err.data.error, | ||
}; | ||
let newErr = new Error('OpenSearch error: ' + message); |
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 needed to change this to an Error
type to catch it properly in OpenSearchDetails.tsx
value.jsonData.flavor} ${value.jsonData.version}`; | ||
} | ||
|
||
const getServerlessSettings = (event: React.SyntheticEvent<HTMLInputElement, Event>) => { |
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.
All of the query code assumes that a version and flavor are set, so rather than refactor that in this commit, I set the flavor and version when serverless is toggled. (I checked and you cannot get a version from serverless). I figured just setting it to the latest one was ok, as we'll need to go make other code changes anyway if a new latest version introduces breaking changes.
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 we need a version/flavor if it's serverless? Aren't all serverless the same flavor/version?
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.
Yup, serverless are all the same! but (at least at present) our query code expects a version to be set, so we need one to be set.
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 tested this with a serverless datasource and the flow as a bit weird:
Screen.Recording.2023-05-03.at.1.30.10.PM.mov
what if when we get/set version we check if it's serverless based on the url and then set the toggle?
I think we should be able to dynamically determine it based on the url, I think for example most of the endpoints are formatted like https://{someidorsomething}.{region}.aoss.amazonaws.com
I wonder if we could do a regex for aoss.amazonaws.com
and if it's there we set the version to serverless or something?
useEffect(() => { | ||
setSaved(false); | ||
}, [ | ||
options.url, |
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 is probably excessive, but since the user has to click a button to save it anyway, I figured it was better to err on the side of re-saving too often.
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.
Looking cool!
I don't love the concept of having save and get version in the same button, but I also get that in this case it might make sense because you can't detect the version without saving your auth settings.
Another question that I'm only just thinking through now, is there a reason we have to surface this to users at all? What if testDatasource was responsible for getting/setting the opensearch version and we didn't show a field for this at all?
src/configuration/ConfigEditor.tsx
Outdated
} | ||
await getBackendSrv() | ||
.put(`/api/datasources/${options.id}`, options) | ||
.then((result: { datasource: any }) => { |
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.
nitpicky but just sharing for knowledge in case its fun to rewrite async js :D that when you have await you don't need to use .thens so this could be rewritten as:
const { datasource} = await getBackendSrv().put(`/api/datasources/${options.id}`, options);
options.version = darasource.version;
....
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
expect(last(onChangeMock.mock.calls)[0].jsonData.flavor).toBe(Flavor.OpenSearch); | ||
expect(last(onChangeMock.mock.calls)[0].jsonData.version).toBe('2.6.0'); | ||
|
||
// rerender with the changed 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.
neat I don't think I've used this before :)
@@ -143,10 +171,15 @@ describe('OpenSearchDetails', () => { | |||
const onChangeMock = jest.fn(); | |||
|
|||
const defaultConfig = createDefaultConfigOptions(); | |||
const opensearchDetectVersionValue = config.featureToggles.opensearchDetectVersion; |
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.
might make sense to take this out of the describe, it's very unlikely but I guess I could see a world where we edit config.featureToggles.opesearchDetectVersion directly in a previous test up above and accidentally never reset it or something?
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.
like this?
value.jsonData.flavor} ${value.jsonData.version}`; | ||
} | ||
|
||
const getServerlessSettings = (event: React.SyntheticEvent<HTMLInputElement, Event>) => { |
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 we need a version/flavor if it's serverless? Aren't all serverless the same flavor/version?
src/datasource.ts
Outdated
` is not supported by the OpenSearch plugin. Use the ElasticSearch plugin.`, | ||
}); | ||
} | ||
//https://grafana.com/docs/grafana/latest/datasources/elasticsearch/ |
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.
nice addition! Maybe we can share a link somehow?
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 commented out link was from when I was trying to add the link. I couldn't get it to render properly 😞, whatever calls testDatasource
displayed the whole href block.
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.
Another question that I'm only just thinking through now, is there a reason we have to surface this to users at all? What if testDatasource was responsible for getting/setting the opensearch version and we didn't show a field for this at all?
That was more or less proposal 1! I think we decided not to do that so that the users would be aware that the version has to be reset if they update their OpenSearch instance.
src/configuration/ConfigEditor.tsx
Outdated
} | ||
await getBackendSrv() | ||
.put(`/api/datasources/${options.id}`, options) | ||
.then((result: { datasource: any }) => { |
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
@@ -143,10 +171,15 @@ describe('OpenSearchDetails', () => { | |||
const onChangeMock = jest.fn(); | |||
|
|||
const defaultConfig = createDefaultConfigOptions(); | |||
const opensearchDetectVersionValue = config.featureToggles.opensearchDetectVersion; |
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.
like this?
value.jsonData.flavor} ${value.jsonData.version}`; | ||
} | ||
|
||
const getServerlessSettings = (event: React.SyntheticEvent<HTMLInputElement, Event>) => { |
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.
Yup, serverless are all the same! but (at least at present) our query code expects a version to be set, so we need one to be set.
src/datasource.ts
Outdated
` is not supported by the OpenSearch plugin. Use the ElasticSearch plugin.`, | ||
}); | ||
} | ||
//https://grafana.com/docs/grafana/latest/datasources/elasticsearch/ |
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 commented out link was from when I was trying to add the link. I couldn't get it to render properly 😞, whatever calls testDatasource
displayed the whole href block.
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.
nice, tested out with es and os and works for me. just a comment about providing an error message earlier about the unsupported version when the save and get version button is pressed.
src/datasource.ts
Outdated
@@ -630,6 +644,15 @@ export class OpenSearchDatasource extends DataSourceApi<OpenSearchQuery, OpenSea | |||
return JSON.stringify(queryObj); | |||
} | |||
|
|||
async getOpenSearchVersion(): Promise<{ flavor: Flavor; version: 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.
nit: can we export the Version
interface from here and use that 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.
done!
setVersionErr(''); | ||
await saveOptions(); | ||
try { | ||
const version = await datasource.getOpenSearchVersion(); |
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.
can getOpenSearchVersion
check for supported versions and throw an error if it's >=7.11.0? right now it can successfully set a version and it appears to be ok, but i don't see an error until i save and test the datasource.
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!
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.
Made Kevin's changes. Still could not figure out how to get the Alert to render with a link 😞
src/datasource.ts
Outdated
@@ -630,6 +644,15 @@ export class OpenSearchDatasource extends DataSourceApi<OpenSearchQuery, OpenSea | |||
return JSON.stringify(queryObj); | |||
} | |||
|
|||
async getOpenSearchVersion(): Promise<{ flavor: Flavor; version: 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.
done!
setVersionErr(''); | ||
await saveOptions(); | ||
try { | ||
const version = await datasource.getOpenSearchVersion(); |
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!
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.
Cool stuff!
I was playing around with this and one thing I could see happening is users click Save and Get Version misread this as Get and Save and think that their version is saved as well? I do sort of wonder if we should just call it Get Version after all? Or alternatively we could save again after the version is set? Idk what do you think? Am I overthinking this? It's a tricky ui question here
Screen.Recording.2023-05-03.at.1.44.10.PM.mov
Also had an idea for optimizing the serverless flow. But also these suggestions feel like things we could explore in future issues/prs if we want to merge as is I'm down!
const { Select, Switch } = LegacyForms; | ||
|
||
const opensearchDetectVersionValue = config.featureToggles.opensearchDetectVersion; |
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.
yeah this is what I meant!
const { Select, Switch } = LegacyForms; | ||
|
||
const opensearchDetectVersionValue = config.featureToggles.opensearchDetectVersion; | ||
|
||
afterAll(() => { |
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.
does this work when it's outside of the describe? it might have to be inside? Please go ahead and tell me if I'm wrong tho haha
value.jsonData.flavor} ${value.jsonData.version}`; | ||
} | ||
|
||
const getServerlessSettings = (event: React.SyntheticEvent<HTMLInputElement, Event>) => { |
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 tested this with a serverless datasource and the flow as a bit weird:
Screen.Recording.2023-05-03.at.1.30.10.PM.mov
what if when we get/set version we check if it's serverless based on the url and then set the toggle?
I think we should be able to dynamically determine it based on the url, I think for example most of the endpoints are formatted like https://{someidorsomething}.{region}.aoss.amazonaws.com
I wonder if we could do a regex for aoss.amazonaws.com
and if it's there we set the version to serverless or something?
src/datasource.test.ts
Outdated
datasourceRequestMock.mockImplementation(() => { | ||
return Promise.resolve({ data: { version: { number: '7.11.1' } } }); | ||
}); | ||
//'ElasticSearch version 7.11.1 is not supported by the OpenSearch plugin. Use the ElasticSearch plugin.' |
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.
is this comment left over from development?
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.
yup, oops
What this PR does / why we need it:
Currently, opensearch uses a drop down menu in the config form to get the version. This is inconvenient for users and requires us to maintain the list of OpenSearch versions (which we aren't really doing). This commit exchanges the menu for a button that saves the config (to make sure it connects properly) and detects the version. It's behind the
opensearchDetectVersion
feature flag.Before:
The new ui:
When the call to get the version fails:
It was also changed to default to a null version (so the user has to set it to successfully configure the datasource) and for test to error when the elasticsearch version is >= 7.11.0. I can remove those changes if we think they're unnecessary.
Error for a too high elasticsearch version:
Which issue(s) this PR fixes:
Fixes #132 #131
Special notes for your reviewer:
If you want to test this with elasticsearch, you can run
make devenv sources=elastic
in the main grafana repo to connect tohttp://localhost:9200/
ormake devenv sources=elastic elastic_version=7.10.0
to pick a specific version. (Runmake devenv-down
to take them down after)