I am trying to use Foreman_hooks to provision our IPAM (Netbox) during Host creation.
I managed to do it during the create event, but the data sent to my script by Foreman is very poor : there is not enough information for our IPAM (as vcpus, memory, disk, netmask, cluster name, etc…).
So, I modified my script so that it uses Foreman API (/api/hosts/:id/vm_compute_attributes) to gather those information.
Problem is that, during create event, the Host is not yet created and the API call returns “host does not exists”.
So I tried with after_create event, same problem.
I also tried the postcreate event (as documented), but this event is never triggered (and it does not even appear in the foreman-rake hooks:events[host/managed] list…)
Then, I tried with the after_commit event, and then it worked. But the problem is that this event seems also to be triggered for a lot of other Hosts already that were created before, I don’t understand why…
Can someone explain to me when exactly are the different event triggered ?
What is the right way to achieve what I’m trying to do ?
Major problem with hooks is that this is tightly coupled with Rails ActiveRecord stack, particularly it’s callback system which also change over time. Some related objects are not available until after_commit. Also it renders JSON via our HAML/API templates, so it can only provide what’s available there.
All I can recommend for now is to forget about the incoming JSON and make your API request to get the data. The problem is that you should not do the request the moment you get called because the data was not yet commited to database so the other request would not see them. So terrible hack and idea but save the event to some queue, wait a bit and then pull the required data via API and do your actions.
This is actually what I would like to propose - to replace foreman_hooks with a simple callbacks hooked on controller level and published via Redis Queues, which we currently consider adding into the project.
I have a simple create hook that touches a file (named after the host) and my after_commit hook only executes if the file exists. It deletes the file before doing any work, thereby eliminating the possibility of the hook executing twice if 2 after_commit events fired in rapid succession.