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 done.
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:
result = super(user_add, self).execute(stuff)
# some extra work
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 case.
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?
Assuming it is right, the only issue I have is an impact to third-party
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
/ Alexander Bokovoy
Sr. Principal Software Engineer
Security / Identity Management Engineering
Red Hat Limited, Finland