1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

add api urls and signals interface for detail route buttons

This commit is contained in:
John Anderson
2020-03-01 03:24:17 -05:00
parent a17c22746d
commit 71a8a13644
8 changed files with 87 additions and 9 deletions

View File

View File

@ -0,0 +1,34 @@
import django.dispatch
from django.dispatch.dispatcher import NO_RECEIVERS
class PluginSignal(django.dispatch.Signal):
def _sorted_receivers(self, sender):
orig_list = self._live_receivers(sender)
sorted_list = sorted(
orig_list,
key=lambda receiver: (
receiver.__module__,
receiver.__name__,
)
)
return sorted_list
def send(self, sender, **kwargs):
responses = []
if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS:
return responses
for receiver in self._sorted_receivers(sender):
response = receiver(signal=self, sender=sender, **kwargs)
responses.append((receiver, response))
return responses
"""
This signal collects templates which render buttons for object detail pages
"""
register_detail_page_buttons = PluginSignal(
providing_args=[]
)

View File

@ -0,0 +1,27 @@
from django import template as template_
from django.template.loader import get_template
from django.utils.safestring import mark_safe
from extras.plugins.signals import register_detail_page_buttons
register = template_.Library()
@register.simple_tag()
def plugin_buttons(obj):
"""
Fire signal to collect all buttons registered by plugins
"""
html = ''
responses = register_detail_page_buttons.send(obj)
for receiver, response in responses:
if not isinstance(response, list):
response = [response]
for template in response:
if isinstance(template, str):
template_text = get_template(template).render({'obj': obj})
html += template_text
return mark_safe(html)

View File

@ -261,7 +261,7 @@ INSTALLED_APPS = [
] ]
# Middleware # Middleware
MIDDLEWARE = ( MIDDLEWARE = [
'debug_toolbar.middleware.DebugToolbarMiddleware', 'debug_toolbar.middleware.DebugToolbarMiddleware',
'django_prometheus.middleware.PrometheusBeforeMiddleware', 'django_prometheus.middleware.PrometheusBeforeMiddleware',
'corsheaders.middleware.CorsMiddleware', 'corsheaders.middleware.CorsMiddleware',
@ -277,7 +277,7 @@ MIDDLEWARE = (
'utilities.middleware.APIVersionMiddleware', 'utilities.middleware.APIVersionMiddleware',
'extras.middleware.ObjectChangeMiddleware', 'extras.middleware.ObjectChangeMiddleware',
'django_prometheus.middleware.PrometheusAfterMiddleware', 'django_prometheus.middleware.PrometheusAfterMiddleware',
) ]
ROOT_URLCONF = 'netbox.urls' ROOT_URLCONF = 'netbox.urls'
@ -622,12 +622,12 @@ for entry_point in iter_entry_points(group='netbox.plugin', name=None):
# Add middleware # Add middleware
plugin_middleware = getattr(app_config_meta, 'middleware', []) plugin_middleware = getattr(app_config_meta, 'middleware', [])
if plugin_middleware: if plugin_middleware and isinstance(plugin_middleware, list):
MIDDLEWARE.extend(plugin_middleware) MIDDLEWARE.extend(plugin_middleware)
# Add middleware # Add installed apps
plugin_installed_apps = getattr(app_config_meta, 'installed_apps', []) plugin_installed_apps = getattr(app_config_meta, 'installed_apps', [])
if plugin_installed_apps: if plugin_installed_apps and isinstance(plugin_installed_apps, list):
INSTALLED_APPS.extend(plugin_installed_apps) INSTALLED_APPS.extend(plugin_installed_apps)
# Verify required configuration settings # Verify required configuration settings

View File

@ -70,18 +70,31 @@ _patterns = [
# Plugins # Plugins
plugin_patterns = [] plugin_patterns = []
plugin_api_patterns = []
for app in apps.get_app_configs(): for app in apps.get_app_configs():
if hasattr(app, 'NetBoxPluginMeta'): if hasattr(app, 'NetBoxPluginMeta'):
if importlib.util.find_spec('{}.urls'.format(app.name)): if importlib.util.find_spec('{}.urls'.format(app.name)):
urls = importlib.import_module('{}.urls'.format(app.name)) urls = importlib.import_module('{}.urls'.format(app.name))
url_slug = getattr(app.NetBoxPluginMeta, 'url_slug', app.label) url_slug = getattr(app.NetBoxPluginMeta, 'url_slug', app.label)
plugin_patterns.append( if hasattr(urls, 'urlpatterns'):
path('{}/'.format(url_slug), include((urls.urlpatterns, app.label))) plugin_patterns.append(
) path('{}/'.format(url_slug), include((urls.urlpatterns, app.label)))
)
if importlib.util.find_spec('{}.api'.format(app.name)):
if importlib.util.find_spec('{}.api.urls'.format(app.name)):
urls = importlib.import_module('{}.api.urls'.format(app.name))
if hasattr(urls, 'urlpatterns'):
url_slug = getattr(app.NetBoxPluginMeta, 'url_slug', app.label)
plugin_api_patterns.append(
path('{}/'.format(url_slug), include((urls.urlpatterns, app.label)))
)
_patterns.append( _patterns.append(
path('plugins/', include((plugin_patterns, 'plugins'))) path('plugins/', include((plugin_patterns, 'plugins')))
) )
_patterns.append(
path('api/plugins/', include((plugin_api_patterns, 'plugins-api')))
)
if settings.DEBUG: if settings.DEBUG:
import debug_toolbar import debug_toolbar

View File

@ -3,6 +3,7 @@
{% load static %} {% load static %}
{% load helpers %} {% load helpers %}
{% load custom_links %} {% load custom_links %}
{% load plugins %}
{% block title %}{{ device }}{% endblock %} {% block title %}{{ device }}{% endblock %}
@ -36,6 +37,7 @@
</div> </div>
</div> </div>
<div class="pull-right noprint"> <div class="pull-right noprint">
{% plugin_buttons device %}
{% if show_graphs %} {% if show_graphs %}
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#graphs_modal" data-obj="{{ device.name }}" data-url="{% url 'dcim-api:device-graphs' pk=device.pk %}" title="Show graphs"> <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#graphs_modal" data-obj="{{ device.name }}" data-url="{% url 'dcim-api:device-graphs' pk=device.pk %}" title="Show graphs">
<i class="fa fa-signal" aria-hidden="true"></i> <i class="fa fa-signal" aria-hidden="true"></i>

View File

@ -2,6 +2,7 @@
{% load buttons %} {% load buttons %}
{% load custom_links %} {% load custom_links %}
{% load helpers %} {% load helpers %}
{% load plugins %}
{% load static %} {% load static %}
{% load tz %} {% load tz %}
@ -33,6 +34,7 @@
</div> </div>
</div> </div>
<div class="pull-right noprint"> <div class="pull-right noprint">
{% plugin_buttons site %}
{% if show_graphs %} {% if show_graphs %}
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#graphs_modal" data-obj="{{ site.name }}" data-url="{% url 'dcim-api:site-graphs' pk=site.pk %}" title="Show graphs"> <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#graphs_modal" data-obj="{{ site.name }}" data-url="{% url 'dcim-api:site-graphs' pk=site.pk %}" title="Show graphs">
<i class="fa fa-signal" aria-hidden="true"></i> <i class="fa fa-signal" aria-hidden="true"></i>