-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Implement webhook events system #81
Comments
WHMCS has a pretty nice hook system that one could look to... Basically every system action would have a pre and post action hook... Hooks are defined for these actions and a numerical id assigned on each so they can be processed in a specific order Reference: http://docs.whmcs.com/Hooks |
Perhaps using the webhooks or an API to allow connection to PowerDNS to handle PTR records for ip allocations. |
A simple solution may be to use the django signals : https://docs.djangoproject.com/en/1.9/ref/signals/ We can make a system which listens to these signals on every model, and also to the signal emitted when a HTTP request happens (to detect every access to netbox). This system could then call some user-specified scripts, in a specific folder for instance. What about it ? |
Hi, I have made a hook system for Netbox, you can currently see it on my fork, in the branch "hooks". It's very simple : there is a folder "userscripts", every script in it is automatically loaded and can connect receivers to django signals. No action is needed to load the scripts. No action will be needed to add support for future models. Django doesn't emit any signal on a bulk edit, so I created a signal for it, which can be listened the same way. Below is the doc I have written for this system and an example of a listening script (that I included in the commit), please tell me what you think about it.
|
I added to userscripts a logging utility and the ability to be called through a HTTP request. It allows for instance to call a script daily from a cron instead of each time an event occurs. New doc :
New example script : https://github.com/rdujardin/netbox/blob/hooks/netbox/userscripts/example.py |
This would be such a great feature to connect many external systems. An implementation would be awesome! 😃 |
I think what @rdujardin proposed is exactly what most organizations are looking for. It is also exactly what I need. I like the idea to use Django signals and hopefully this approach would be something what jeremystretch could easily adopt. This feature request is very important since it allows the integration of third-party tools without having to write a specific "module" for each third-party solution/vendor. In my organization, we'd use such a feature to automatically handover data from NetBox to our own APIs which take care of LDAP, DNS, third-party support tools etc. In my eyes, this GitHub issue actually covers something I'd consider as a "basic feature" for a decent DCIM solution. And who knows - maybe some people didn't switch to NetBox yet because they are waiting for exactly this feature. |
Another +1 for this feature. In my current custom IPAM solution, we have code that automatically talks to the Infoblox API to add DNS entries if desired. The ability to extend the Netbox functionality to other systems would be very valuable. |
+1 from me, as I'd like to let netbox talk to Microsoft DNS and DHCP Server vis custom scripts/plugins/API calls/ect. |
Also throwing in support for this. One very big use cases I have for this ties in with #150 (vlan port mapping). When a vlan is changed on a port, a webhook is fired off to an automation platform to enact that change. |
This could be achieved through celery tasks but that would also increase
installation complexity...
…On Thu, Mar 2, 2017, 15:32 John Anderson, ***@***.***> wrote:
Also throwing in support for this. One very big use cases I have for this
ties in with #150 <#150>
(vlan port mapping). When a vlan is changed on a port, a webhook is fired
off to an automation platform to enact that change.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#81 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABfg5gS-a7R9sXLGZxSrW_Trhq2yAh5pks5rhydagaJpZM4JALE9>
.
|
I love seeing features like this become implemented into such powerful software. Is there any chance that anyone has an example of what an integration with WHMCS or PHPIPAM would look like? Not a coder myself... |
I'd like to implement this in a manner similar to how GitHub does it: Select the models and events you're interested, and tell NetBox what URL to hit when something happens. NetBox would then POST a JSON representation of that event to the specified URL. As @rdujardin suggested, we can leverage Django signals to accomplish this. However, I'd like to store webhooks in the database rather than as user-created scripts. We should still be able to support customization by templatizing the request body. I'm curious what people would expect the body of the POST request to look like. |
I would probably expect something like the contents of an object that was just added, updated, or deleted, as well as some metadata that talks about the type of event, the time it occurred, the user who performed the action, etc. JSON POST body all the way. |
I am going to start a WIP for this. Here is my initial though process. To make this worthwhile it is going to require a persistent back end worker, so these actions happen in the background and we can handle things like retries in a proper manor. My thought is to build this functionality out but not enable it by default as this is really a power user feature anyway. I want to use python-rq for its relative simplicity. This means, to enable the feature, the user will have to install redis and somehow start the background worker process (most likely just as an option when starting the server). I do like @jeremystretch's idea to model it after github's implementation. Ideally the event triggers will be fired by Django signals and the background worker will figure out what to do based on the webhook(s) the user defines. |
As a follow up to where I am at with this. I have a fully functional implementation and am working out some of the details now. In an effort to adhere to the 80/20 rule here is how I have chosen to implement it: These models may have zero or more webhooks registered them (similar to how custom fields work):
Each of these models may have webhooks registered to one or more of these signals:
The Webhook model resides in extras and is accessed through the admin site. It looks like this:
The actual POST request is formatted like this using the model's api serializer (using application/json content type):
I consider this an "advanced feature" and like the napalm integration, takes a little bit of extra effort from the user to enable it. That is to say, the internal functionality is all there but ships disabled. To enable it, the user will have to preform these steps:
I am currently coming up with an elegant way to start the python-rq background worker process from within the same supervisor unit that netbox uses in the install docs. In my current implementation the user would have to start this separately. If the feature is not enabled in the configuration, netbox will never try to import When enabled there are some safeguards to ensure everything is ready. Namely when netbox is starting up it will ensure On startup, each app registers applicable models to the two generic signal receiver functions in When a model signal is fired, it is received by the appropriate receiver function (post_save vs. post_delete). If the webhook feature is enabled, we retrieve the webhook cache and look for any and all webhooks which meet the criteria for this signal. For each matching webhook found, enqueue a job into django-rq (the 'default' job queue is the only one implemented). The background worker will then process anything in the queue. The POST request is built and then made to the payload url. If a good status code (from the python requests definition) is returned, the job is successful, otherwise it has failed and django-rq puts the job in the "failed" queue. Django-rq also implements an admin view which allows the user to view the status of the job queue(s). There the result of jobs can be seen and failed jobs can be manually retried. This is my first iteration but it seems to be working quite well :) |
Hi and thank you for your wonderful work! Am I right to assume that this code is supposed to allow the calling of external utilities (e.g. certain binaries on the Netbox host) in case somebody performs a certain change using the API or the web interface? Based on the code, I am not sure how I would create the "external command" redirection ... |
@madkiss not exactly. You are correct in that it is used to interact with external systems. However it is mean to interface with HTTP systems. Specifically the way #1640 is implemented, when registered models are created/updated/deleted, a HTTP POST request is made to one or more user configured URLs. The payload of the request includes the model data and the event type. |
So my first iteration over this (#1640) was very inlightning. Several things came up that need to be addressed in a further implementation attempt. Basically, I used a property on each Model to link it to its respective API serializer and then dynamically imported those when needed. The django rest framework requires the request be passed in when constructing a serializer with a model instance (for The main issue resides in the bulk update views. These views use the queryset Another "annoying" implementation detail was the way in which I registered the models to the signal receivers. Ultimately this can be refactored but I am not sure of the related performance hit. django-rq worked out nicely and provided just the base level of functionality needed to implement the job queue without adding the tremendous complexity and overhead that celery imposes. In all, the implementation in the PR was "ok" for a very generic approach and in fact I am using it in another project in which the above considerations are not of the same concern to me at this time. I think for this to truly succeed, we should actually take a step back and create our own signals. Otherwise we would need a hack to use the build in @jeremystretch I see you are considering this feature request. Do you have any thoughts? I would be more than happy to dig into this more with you. |
After some thought, I came back to this and refactored my first iteration. I think I solved the bulk operation problem and have reopened #1640. If anyone has the time, please try that branch out and let know what you think. |
* merge branch develop * bugfix, signals for virtualization's class wasn't correctly defined * updated webhooks for 2.4 and cleanup * updated docs to cover changes to supervisor config * review changes and further cleanup * updated redis connection settings * cleanup settings
Yes! Thanks so much @lampwins for doing this! Can't wait to give this a shot in our production environment. |
@WilliamMarti we are also using infoblox in our organization, we are planning to adopting with netbox so Could you elaborate bit more about your setup & how compatible/easy to ingrate infoblox - netbox, it will really great to hear 👍 Thanks. |
To allow NetBox to become more extensible while still keeping its code clean and focused, a webhooks system could be implemented, enabling hooks to fire when certain events take place.
This might be a ways out, but it's worth thinking about at least. Proposed as an idea to solve #63 and #77 in a more generic way.
The text was updated successfully, but these errors were encountered: