-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
Handling saved object references in expressions #59960
Comments
Pinging @elastic/kibana-app-arch (Team:AppArch) |
PlanWe'll go with Option 2 (Only keep reference names in expressions) and made the following decisions: The The phasing is the following
Optional (in the sense of the migration):
|
i think we need to recognize the difference between having an expression inside kibana at runtime and between persisting the expression. When we are not persisting the expression (saved object, url, ...) there is no problem with keeping references inside the expressions. The only time we need to extract them is when we are persisting them. This is pretty much the same as with any state we want to persist, thats why we are thinking about implementing a global service to tackle this issue #62950 with this approach expressions can keep the references for as long as they they are not persisted. the persister needs to ask expression service to convert the expression into a version that can be persisted. At this point expression service will extract all the references and possibly to other changes to expression, return the new expression and the references array. when loading them we need to ask expression service to inject the references. in general, any plugin exposing any persistable state (state that can be persisted) would need to register with our service its state id together with migration, reference extraction and reference injection functions. with expressions specifically this is gonna be a two layer implementation. Expression service will register its injectReferences function, which will:
|
@ppisljar based on what you're saying above, is #63358 going to supersede this issue, or is #63358 just the underlying infrastructure that will enable us to resolve this issue? I'm trying to get a sense of a timeline for this, as it's necessary in order for virtually any of our existing saved objects to become sharable between spaces. The security team isn't blocked on this yet, but at some point we will have all of our pieces in place to migrate these existing objects, and that's something we'd love to do in 7.x if possible. |
underlying infrastructure was provided in #72438 remaining work is now providing extract and inject functons for each of expression functions accepting references to saved objects as arguments (listed above). kibana_context refactoring is planned for 7.11/7.12 we will most likely also provide extract/inject functions for our there are also some canvas expression functions which will need to provide those. |
Thanks for the clarification and update, @ppisljar! If you could keep this issue updated with the team's progress over the next couple of minors, that would be greatly appreciated |
@ppisljar Do you have any updates on this? |
This continues to be pushed back due to other things getting a higher priority. Work on kibana_context function is planned again for 7.13 hopefully it does happen this time. |
Via #59598 and the resulting meetings we've figured out, that we will definitely run into situations where ids of saved objects might change and saving ids of saved objects inside any saved object part can break. Therefore saved objects have a
references
concept where they can reference other saved objects. Other fields within the saved objects should now only contain the reference name and the consumer of the saved object need to take care about looking that name up in the references.We have some places we need references in expression, e.g. the index pattern id in
esaggs
, the saved object id in canvas embeddable functions. Currently we store theid
of the saved object directly in that. We need to make sure this is using references as well, so the changes in id of the references saved objects will be handled correctly by the saved object system.I see currently two main methods of handling this:
For both of those cases, it makes sense to mark references to other saved object as such. The suggestion we talked about so far would be, to introduce a
reference
function via the coreexpressions
plugin for that. This one will be used whenever you need to reference a saved object, so that a (simplified) correct expression would look like follows:If we don't mark those explicitly, we would need to have implicit knowledge about what inside an expression could be a saved object id and what just a regular string, which sounds like a very unsafe solution.
Since we still need to write references correctly into the saved object (since otherwise export/import also breaks), the
expressions
plugin itself could also export a method to retrieve now all references from an expression:This can be called by the application when it saves the SavedObject to extract references from the expression.
Every saved object that currently still has ids inside expressions in it, will need to write a migration to properly extract them into the
references
array.Explicitly update references
For this approach to happen, we'd assume that we have a way to let the core saved object system notify us about id changes. So we could plug in a callback, that will be called on our "saved object", whenever the id of one of its references change, e.g.
onReferencesIdsChanged(changedId: Record<{ type: string; id: string }, string>) => void
(mapping old types/ids to new ones).An implementation of that method, would now replace the ids in the
reference
function parameters with the new ones. Theexpressions
plugin should offer a utility that does that (updateReferences(expression: string | Ast, changedIds: Record<{ type: string; id: string}, string>) => Ast
).Advantages
Disadvantages
SavedObject
class that a plugin would need to implement, so we currently don't have a clear place where this method would need to go, so most likely it would be a new registry mapping saved object ids, toonReferencesIdsChanged
callbacks.Only keep reference names in expressions
This approach assumes, we're never actually saving ids in the expression, but instead storing expressions only with reference names. This means the
extractReferences
method would not only return us a the references inside the expression, but also a rewritten expression, that will now only have reference names in it, e.g.:Whenever we load that saved object now, we basically would use a reverse (insert) method in the
expressions
plugin to convert that saved expression and an array of references back into the original expression.Advantages
Disadvantages
The text was updated successfully, but these errors were encountered: