[Infrastructure UI] Implement inventory views CRUD endpoints#154900
[Infrastructure UI] Implement inventory views CRUD endpoints#154900tonyghiani merged 27 commits intoelastic:mainfrom
Conversation
🤖 GitHub commentsExpand to view the GitHub comments
Just comment with:
|
…-ref HEAD~1..HEAD --fix'
|
Pinging @elastic/infra-monitoring-ui (Team:Infra Monitoring UI) |
yngrdyn
left a comment
There was a problem hiding this comment.
Changes in kbn-io-ts-utils package LGTM
|
|
||
| export type InventoryViewRequestQuery = rt.TypeOf<typeof inventoryViewRequestQueryRT>; | ||
|
|
||
| const inventoryViewAttributesResponseRT = rt.intersection([ |
There was a problem hiding this comment.
note: for the attributes of this saved object, the configuration has always been dynamic and not strictly typed. As they can vary depending on the user usage on the page, I left it open to all the attributes as it was before, marking only those that I'm sure will be present in the response.
This applies to any other attributes definition you'll find for this attribute's saved object.
| isDefault: rt.boolean, | ||
| isStatic: rt.boolean, |
There was a problem hiding this comment.
note:
isDefaultrepresent whether a saved view is the default one by user preference.isStaticis used to distinguish the static saved view that will always be present and served, now hardcoded in the server and not configurable.
There was a problem hiding this comment.
Can those values change using the API? For example, using the update endpoint to set another default view?
There was a problem hiding this comment.
As those values are derived as:
isDefault: match with theinventoryDefaultViewconfiguration saved in the source configurationisStaticis a statically set value tofalse
They could insert those values triggering a manual request to the endpoint, but I guess is better to handle the case, I'll change that!
There was a problem hiding this comment.
note: moved the inventory-view saved object type here among the others, with #155117 I'll clean up the legacy usage of this SO defined in common/saved_objects. (Same applies for the metrics-explorer-view SO)
| private readonly infraSources: IInfraSources | ||
| ) {} | ||
|
|
||
| static STATIC_VIEW_ID = '0'; |
There was a problem hiding this comment.
note: keep the previous id for the static view always present.
I initially wanted to change it to the static string, but as it relies on a value saved in the infrastructure-ui-source SO, changing it would imply also writing a migration for that SO, resulting in overengineering a simple rename.
| const defaultView = InventoryViewsClient.createStaticView( | ||
| sourceConfiguration.configuration.inventoryDefaultView | ||
| ); | ||
| const views = inventoryViewSavedObject.saved_objects.map((savedObject) => | ||
| this.mapSavedObjectToInventoryView( | ||
| savedObject, | ||
| sourceConfiguration.configuration.inventoryDefaultView | ||
| ) | ||
| ); | ||
|
|
||
| const inventoryViews = [defaultView, ...views]; | ||
|
|
||
| const sortedInventoryViews = this.moveDefaultViewOnTop(inventoryViews); |
There was a problem hiding this comment.
note: When getting all the available inventory views, we want them to:
- Always include the hardcoded static inventory view.
- Map into a reduced version to avoid large payloads.
- Sorted by creation date, but having on top the default view selected by the user.
To calculate which one is the default view and not delegate this to the client, we retrieve in parallel the source configuration to compute in runtime the isDefault attribute for each inventory view.
| private async assertNameConflict(name: string, whitelist: string[] = []) { | ||
| const results = await this.savedObjectsClient.find<InventoryViewAttributes>({ | ||
| type: inventoryViewSavedObjectName, | ||
| perPage: 1000, | ||
| }); | ||
|
|
||
| const hasConflict = [InventoryViewsClient.createStaticView(), ...results.saved_objects].some( | ||
| (obj) => !whitelist.includes(obj.id) && obj.attributes.name === name | ||
| ); | ||
|
|
||
| if (hasConflict) { | ||
| throw Boom.conflict('A view with that name already exists.'); | ||
| } | ||
| } |
There was a problem hiding this comment.
note: we can't delegate this search to the savedObjectsClient.find method since, being the attributes mapping set to dynamic: false, searching for the name won't return results.
jennypavlova
left a comment
There was a problem hiding this comment.
Great work 👏
Tried the requests, and everything worked 🎉 I have several questions regarding the update endpoint (it should be PUT not POST right? - the PR description can be updated in that case)
- I tried to update
isStaticorisDefaultand didn't work - that is correct, right? Only the name can be changed? - The default view can't be updated/deleted right? Because the API returns 404 if I try to (using
0as id).
| isDefault: rt.boolean, | ||
| isStatic: rt.boolean, |
There was a problem hiding this comment.
Can those values change using the API? For example, using the update endpoint to set another default view?
|
|
||
| return response.noContent(); | ||
| } catch (error) { | ||
| if (isBoom(error)) { |
There was a problem hiding this comment.
Nit: If the id is set to 0 (Default view id) the response is 404, should we have a message explaining that the default view can't be deleted or something like that - because the view is returned from the GET and maybe this can be confusing 🤔
There was a problem hiding this comment.
In the client will not be possible to delete the static view, and in case they try to do it manually, they'll get the 404 value, but I agree it could be confusing, I'll introduce an error for this case to handle it
| } | ||
| ``` | ||
|
|
||
| ## Update one: `PUT /api/infra/inventory_views/{inventoryViewId}` |
There was a problem hiding this comment.
Should we mention which properties can be updated?
|
Thanks for the review Jenny!
Correct, it is implemented as a PUT, it was my mistake on the PR description, corrected 👍
Exactly, those values are not writable, I'll take care of updating the validation against those two values!
The static view (I called it like this to distinguish it from the default view, which is a preference setting chosen by the user) is not configurable/deletable, I will add proper error handling in case the user attempt to change it. |
jennypavlova
left a comment
There was a problem hiding this comment.
LGTM 🚀 Thank you for adding the changes!
💚 Build Succeeded
Metrics [docs]Module Count
Public APIs missing comments
Async chunks
Public APIs missing exports
Unknown metric groupsAPI count
ESLint disabled line counts
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: |
…ient (#155126) ## 📓 Summary Depends on #154900 Closes #155110 This PR implements the `InventoryViewsService` and `InventoryViewsClient`, injecting an instance of the client in the KibanaContextForPlugin and exposing so a set of utilities to retrieve/update inventory views: - `findInventoryViews` - `getInventoryView` - `createInventoryView` - `updateInventoryView` - `deleteInventoryView` ## 👣 Next steps - Implement #154725 to consume the service --------- Co-authored-by: Marco Antonio Ghiani <marcoantonio.ghiani@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
…lorerViewsClient (#155878) ## 📓 Summary Depends on #154900 Closes #155112 This PR implements the `InventoryViewsService` and `InventoryViewsClient`, injecting an instance of the client in the KibanaContextForPlugin and exposing so a set of utilities to retrieve/update inventory views: - `findMetricsExplorerViews` - `getMetricsExplorerView` - `createMetricsExplorerView` - `updateMetricsExplorerView` - `deleteMetricsExplorerView` ## 👣 Next steps - Implement #154725 to consume the service --------- Co-authored-by: Marco Antonio Ghiani <marcoantonio.ghiani@elastic.co> Co-authored-by: Carlos Crespo <crespocarlos@users.noreply.github.com>
📓 Summary
Part of #152617
Closes #155158
This PR implements the CRUD endpoints for the inventory views.
Following the approach used for the LogViews service, it exposes a client that abstracts all the logic concerned to the
inventory-viewsaved objects.It also follows the guideline provided for Versioning interfaces and Versioning HTTP APIs, preparing for the serverless.
🤓 Tips for the reviewer
You can open the Kibana dev tools and play with the following snippet to test the create APIs, or you can perform the same requests with your preferred client:
👣 Next steps