Alexander Bokovoy wrote:
On ti, 13 huhti 2021, Rob Crittenden via FreeIPA-devel wrote:
> Currently the framework has four types of methods:
> - pre_callback: called before any real work is done. Usually used to
> tune up incoming options
> - execute: does the brute work. For most CRUD plugins this is all done
> in baseldap.py in the LDAP* classes
> - post_callback: supposed to be data cleanup for presentation to the
> caller but in some cases actual work is being done. user-add calls
> ldap.add_entry_to_group for example.
> - exc_callback: special case handling for exceptions
> If you have "work" to be done that would normally be done in execute
> there is no way to do it other than to abuse post_callback to get it
> Overriding execute is only an option if you want to completely replace
> the call, otherwise order execution is going to be strange.
> Say for example in user_add you want to do work after the execute() is
> done so you'd do something like:
> class user_add()
> def execute(stuff):
> result = super(user_add, self).execute(stuff)
> # some extra work
> return result
> The order of execution is:
> This is because the LDAP* baseldap methods handle the pre/post/exc
> callbacks directly. So in order to be able to insert more "work" in
> execute itself we'd need another callback type.
> Why do I want this?
> One feature of post_callback is that for add/mod methods
> ldap.get_entry() is called so we can prepare the final results to be
> returned to the user for display.
> There are cases where the user doesn't need or case to see that result.
> We could save an least one LDAP query by returning only errors in this
> The use case is mostly around bulk operations where the user doesn't
> care about seeing the UID of all users added, for example.
> To do this I think we can skip post_callback altogether, assuming it
> does no real "work".
> In the case of user_add/mod skipping post_callback would save three
> queries: fetch the user, has_keytab and has_password.
> But before re-architecting this I'd like to get some opinions on it.
> I can do a full-blown design if desired.
So your proposal is multi-fold:
- add a callback type that can be used to perform operations that could
always be done as a part of execute() after the main processing of
add/mod was done but before post_callbacks were to be called
- use the result of executing new type callbacks to decide whether to
do or skip post_callback() execution
- move content of post_callback that does not depend on the
availability of the final results into this new callback type
- leave in the post_callback() state only those operations that rely on
the final results
Is this right?
Mostly. I don't expect to skip any execute callbacks but you do raise an
interesting point. What gets passed into and out of each result callback
is still TBD. I think that the baseldap/top-level execute should create
the final result and dn, entry_attrs, etc will be passed around.
Assuming it is right, the only issue I have is an impact to
plugins. We can communicate such change of course but it is going to
break someone's plugin, for sure. So a better documentation would be
Good point. I wonder if we can set a context variable for when in
post_callback that gets used in any baseldap method that does a write so
that an exception is raised. That would certainly get admins attention.
It would also be a bit harsh. We could log something instead but that
would rely on admins to read the logs.