From 5e8b4880aba9a262bd95a01298acd986cc4944b7 Mon Sep 17 00:00:00 2001 From: Vincent Simonin <vincent.simonin@ext.ec.europa.eu> Date: Mon, 3 Jul 2023 18:38:39 +0200 Subject: [PATCH] Add HTTP Header UI * Add HTTP Header for a Mapping * Remove / edit HTTP Header --- .../netbox_rps_plugin/__init__.py | 2 +- .../netbox_rps_plugin/filtersets.py | 19 +++++++- .../netbox_rps_plugin/forms.py | 17 ++++++- .../netbox_rps_plugin/models.py | 3 ++ .../netbox_rps_plugin/navigation.py | 1 - .../netbox_rps_plugin/tables.py | 3 +- .../netbox_rps_plugin/accesslist.html | 44 ------------------- .../netbox_rps_plugin/httpheader/child.html | 40 +++++++++++++++++ .../templates/netbox_rps_plugin/mapping.html | 6 +++ .../netbox_rps_plugin/urls.py | 8 +++- .../netbox_rps_plugin/views.py | 31 ++++++++++--- plugins/netbox-rps-plugin/setup.py | 2 +- 12 files changed, 119 insertions(+), 57 deletions(-) delete mode 100644 plugins/netbox-rps-plugin/netbox_rps_plugin/templates/netbox_rps_plugin/accesslist.html create mode 100644 plugins/netbox-rps-plugin/netbox_rps_plugin/templates/netbox_rps_plugin/httpheader/child.html diff --git a/plugins/netbox-rps-plugin/netbox_rps_plugin/__init__.py b/plugins/netbox-rps-plugin/netbox_rps_plugin/__init__.py index 1cec540..c4fcc6c 100644 --- a/plugins/netbox-rps-plugin/netbox_rps_plugin/__init__.py +++ b/plugins/netbox-rps-plugin/netbox_rps_plugin/__init__.py @@ -5,7 +5,7 @@ class NetBoxRpsConfig(PluginConfig): name = 'netbox_rps_plugin' verbose_name = 'NetBox RPS' description = 'A Netbox plugin to add RPS resources' - version = '0.7.1' + version = '0.8.0' author = "Vincent Simonin" author_email = "vincent.simonin@ext.ec.europa.eu" base_url = 'rps' diff --git a/plugins/netbox-rps-plugin/netbox_rps_plugin/filtersets.py b/plugins/netbox-rps-plugin/netbox_rps_plugin/filtersets.py index f67f8cf..b7658fe 100644 --- a/plugins/netbox-rps-plugin/netbox_rps_plugin/filtersets.py +++ b/plugins/netbox-rps-plugin/netbox_rps_plugin/filtersets.py @@ -1,5 +1,5 @@ from netbox.filtersets import NetBoxModelFilterSet -from .models import Mapping +from .models import Mapping, HttpHeader from django.db.models import Q class MappingFilterSet(NetBoxModelFilterSet): @@ -9,5 +9,20 @@ class MappingFilterSet(NetBoxModelFilterSet): fields = ('id', 'authentication', 'source', 'target', 'Comment') def search(self, queryset, name, value): - return queryset.filter( Q(source__icontains=value) | Q(target__icontains=value) + return queryset.filter( Q(source__icontains=value) | Q(target__icontains=value) | Q(authentication__icontains=value) | Q(Comment__icontains=value)) + +class HttpHeaderFilterSet(NetBoxModelFilterSet): + + class Meta: + model = HttpHeader + fields = ('id', 'name', 'value', 'apply_to') + + def search(self, queryset, name, value): + """Perform the filtered search.""" + if not value.strip(): + return queryset + qs_filter = ( + Q(name__icontains=value) + ) + return queryset.filter(qs_filter) diff --git a/plugins/netbox-rps-plugin/netbox_rps_plugin/forms.py b/plugins/netbox-rps-plugin/netbox_rps_plugin/forms.py index 379c63c..abb293e 100644 --- a/plugins/netbox-rps-plugin/netbox_rps_plugin/forms.py +++ b/plugins/netbox-rps-plugin/netbox_rps_plugin/forms.py @@ -1,7 +1,7 @@ from django import forms from django.utils.translation import gettext as _ from netbox.forms import NetBoxModelForm, NetBoxModelFilterSetForm, NetBoxModelImportForm -from .models import Mapping, AuthenticationChoices +from .models import Mapping, AuthenticationChoices, HttpHeader class MappingForm(NetBoxModelForm): @@ -33,3 +33,18 @@ class MappingImportForm(NetBoxModelImportForm): class Meta: model = Mapping fields = ('source', 'target', 'authentication', 'testingpage', 'webdav') + + +class HttpHeaderForm(NetBoxModelForm): + + class Meta: + model = HttpHeader + fields = ( + 'mapping', 'name', 'value', 'apply_to' + ) + labels = { + 'mapping': 'Mapping', + 'name': 'Name', + 'value': 'Value', + 'apply_to': 'Apply to', + } diff --git a/plugins/netbox-rps-plugin/netbox_rps_plugin/models.py b/plugins/netbox-rps-plugin/netbox_rps_plugin/models.py index f086f88..c678b16 100644 --- a/plugins/netbox-rps-plugin/netbox_rps_plugin/models.py +++ b/plugins/netbox-rps-plugin/netbox_rps_plugin/models.py @@ -101,3 +101,6 @@ class HttpHeader(NetBoxModel): class Meta: unique_together = ['mapping', 'name', 'apply_to'] ordering = ['name'] + + def __str__(self): + return self.name diff --git a/plugins/netbox-rps-plugin/netbox_rps_plugin/navigation.py b/plugins/netbox-rps-plugin/netbox_rps_plugin/navigation.py index ed91ca5..f6aa3b2 100644 --- a/plugins/netbox-rps-plugin/netbox_rps_plugin/navigation.py +++ b/plugins/netbox-rps-plugin/netbox_rps_plugin/navigation.py @@ -32,4 +32,3 @@ menu = ( icon_class='mdi mdi-graph-outline' ) ) - diff --git a/plugins/netbox-rps-plugin/netbox_rps_plugin/tables.py b/plugins/netbox-rps-plugin/netbox_rps_plugin/tables.py index 9920a02..de29258 100644 --- a/plugins/netbox-rps-plugin/netbox_rps_plugin/tables.py +++ b/plugins/netbox-rps-plugin/netbox_rps_plugin/tables.py @@ -21,11 +21,12 @@ class HttpHeaderTable(NetBoxTable): mapping = tables.Column( linkify=True ) + class Meta(NetBoxTable.Meta): model = HttpHeader fields = ( 'pk', 'id', 'name', 'value', 'apply_to', 'mapping' ) default_columns = ( - 'name', 'value' + 'name', 'value', 'apply_to' ) diff --git a/plugins/netbox-rps-plugin/netbox_rps_plugin/templates/netbox_rps_plugin/accesslist.html b/plugins/netbox-rps-plugin/netbox_rps_plugin/templates/netbox_rps_plugin/accesslist.html deleted file mode 100644 index 56972de..0000000 --- a/plugins/netbox-rps-plugin/netbox_rps_plugin/templates/netbox_rps_plugin/accesslist.html +++ /dev/null @@ -1,44 +0,0 @@ -{% extends 'generic/object.html' %} -{% load render_table from django_tables2 %} - -{% block content %} - <div class="row mb-3"> - <div class="col col-md-6"> - <div class="card"> - <h5 class="card-header">Access List</h5> - <div class="card-body"> - <table class="table table-hover attr-table"> - <tr> - <th scope="row">Name</th> - <td>{{ object.name }}</td> - </tr> - <tr> - <th scope="row">Default Action</th> - <td>{{ object.get_default_action_display }}</td> - </tr> - <tr> - <th scope="row">Rules</th> - <td>{{ object.rules.count }}</td> - </tr> - </table> - </div> - </div> - {% include 'inc/panels/custom_fields.html' %} - </div> - <div class="col col-md-6"> - {% include 'inc/panels/tags.html' %} - {% include 'inc/panels/comments.html' %} - </div> - </div> - - <div class="row"> - <div class="col col-md-12"> - <div class="card"> - <h5 class="card-header">Rules</h5> - <div class="card-body table-responsive"> - {% render_table rules_table %} - </div> - </div> - </div> - </div> -{% endblock content %} diff --git a/plugins/netbox-rps-plugin/netbox_rps_plugin/templates/netbox_rps_plugin/httpheader/child.html b/plugins/netbox-rps-plugin/netbox_rps_plugin/templates/netbox_rps_plugin/httpheader/child.html new file mode 100644 index 0000000..031ee55 --- /dev/null +++ b/plugins/netbox-rps-plugin/netbox_rps_plugin/templates/netbox_rps_plugin/httpheader/child.html @@ -0,0 +1,40 @@ +{% extends 'generic/object.html' %} +{% load helpers %} +{% load render_table from django_tables2 %} +{% load perms %} + +{% block extra_controls %} + <a href="{% url 'plugins:netbox_rps_plugin:httpheader_add' %}?mapping={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-sm btn-primary"> + <span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add HTTP Header + </a> +{% endblock %} + +{% block content %} + {% include 'inc/table_controls_htmx.html' with table_modal="HttpHeaderTable_config" %} + + <form method="post"> + {% csrf_token %} + <input type="hidden" name="return_url" value="{% if return_url %}{{ return_url }}{% else %}{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}{% endif %}" /> + + <div class="card"> + <div class="card-body htmx-container table-responsive" id="object_list"> + {% include 'htmx/table.html' %} + </div> + </div> + <div class="noprint bulk-buttons"> + <div class="bulk-button-group"> + {% if 'bulk_delete' in actions %} + <button type="submit" name="_delete" formaction="{% url 'plugins:netbox_rps_plugin:httpheaders_bulk_delete' %}?return_url={% url 'plugins:netbox_rps_plugin:mapping_httpheader' pk=object.pk %}" class="btn btn-danger btn-sm"> + <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete + </button> + {% endif %} + </div> + </div> + </form> + +{% endblock %} + +{% block modals %} + {{ block.super }} + {% table_config_form table %} +{% endblock modals %} diff --git a/plugins/netbox-rps-plugin/netbox_rps_plugin/templates/netbox_rps_plugin/mapping.html b/plugins/netbox-rps-plugin/netbox_rps_plugin/templates/netbox_rps_plugin/mapping.html index 3f148bd..980d6d9 100644 --- a/plugins/netbox-rps-plugin/netbox_rps_plugin/templates/netbox_rps_plugin/mapping.html +++ b/plugins/netbox-rps-plugin/netbox_rps_plugin/templates/netbox_rps_plugin/mapping.html @@ -1,5 +1,11 @@ {% extends 'generic/object.html' %} +{% block extra_controls %} + <a href="{% url 'plugins:netbox_rps_plugin:httpheader_add' %}?mapping={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-sm btn-primary"> + <span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add HTTP Header + </a> +{% endblock %} + {% block content %} <div class="row mb-3"> <div class="col col-md-6"> diff --git a/plugins/netbox-rps-plugin/netbox_rps_plugin/urls.py b/plugins/netbox-rps-plugin/netbox_rps_plugin/urls.py index d1c7d51..47afe99 100644 --- a/plugins/netbox-rps-plugin/netbox_rps_plugin/urls.py +++ b/plugins/netbox-rps-plugin/netbox_rps_plugin/urls.py @@ -19,5 +19,11 @@ urlpatterns = ( }), # HTTP Headers - #path('http-headers/', views.MappingHttpHeadersView.as_view(), name='httpheaders_list'), + path('http-headers/add/', views.HttpHeaderEditView.as_view(), name='httpheader_add'), + path('http-headers/delete/', views.HttpHeaderBulkDeleteView.as_view(), name='httpheaders_bulk_delete'), + path('http-headers/<int:pk>/edit/', views.HttpHeaderEditView.as_view(), name='httpheader_edit'), + path('http-headers/<int:pk>/delete/', views.HttpHeaderDeleteView.as_view(), name='httpheader_delete'), + path('http-headers/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='httpheader_changelog', kwargs={ + 'model': models.HttpHeader + }), ) diff --git a/plugins/netbox-rps-plugin/netbox_rps_plugin/views.py b/plugins/netbox-rps-plugin/netbox_rps_plugin/views.py index 0c6474e..5211b30 100644 --- a/plugins/netbox-rps-plugin/netbox_rps_plugin/views.py +++ b/plugins/netbox-rps-plugin/netbox_rps_plugin/views.py @@ -5,7 +5,7 @@ from utilities.views import ViewTab, register_model_view from django.utils.translation import gettext as _ class MappingView(generic.ObjectView): - queryset = models.Mapping.objects.all() + queryset = models.Mapping.objects.all().prefetch_related('http_headers') class MappingListView(generic.ObjectListView): @@ -35,14 +35,35 @@ class MappingBulkDeleteView(generic.BulkDeleteView): table = tables.MappingTable -#@register_model_view(models.Mapping, 'HTTP Headers', path='http-headers') +@register_model_view(models.Mapping, 'httpheader') class MappingHttpHeadersView(generic.ObjectChildrenView): - queryset = models.Mapping.objects.all() + queryset = models.Mapping.objects.all().prefetch_related('http_headers') child_model = models.HttpHeader table = tables.HttpHeaderTable + filterset = filtersets.HttpHeaderFilterSet + template_name = "netbox_rps_plugin/httpheader/child.html" + hide_if_empty = False + tab = ViewTab( - label=_('HTTP Headers') + label=_('HTTP Headers'), + badge=lambda obj: obj.http_headers.count(), + hide_if_empty=False, ) def get_children(self, request, parent): - return models.HttpHeader.objects.restrict(request.user, 'view').filter(mapping=parent) + return parent.http_headers + + +class HttpHeaderEditView(generic.ObjectEditView): + queryset = models.HttpHeader.objects.all() + form = forms.HttpHeaderForm + + +class HttpHeaderDeleteView(generic.ObjectDeleteView): + queryset = models.HttpHeader.objects.all() + + +class HttpHeaderBulkDeleteView(generic.BulkDeleteView): + queryset = models.HttpHeader.objects.all() + filterset = filtersets.HttpHeaderFilterSet + table = tables.HttpHeaderTable diff --git a/plugins/netbox-rps-plugin/setup.py b/plugins/netbox-rps-plugin/setup.py index ee5203b..74d03c9 100644 --- a/plugins/netbox-rps-plugin/setup.py +++ b/plugins/netbox-rps-plugin/setup.py @@ -2,7 +2,7 @@ from setuptools import find_packages, setup setup( name='netbox-rps-plugin', - version='0.7.1', + version='0.8.0', description='A Netbox plugin to add RPS resources', install_requires=[], packages=find_packages(), -- GitLab