mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
* Replace plugins list with an overall system status view * Enable export of system status data
This commit is contained in:
@ -35,5 +35,5 @@ class PluginTable(BaseTable):
|
|||||||
'name', 'version', 'package', 'author', 'author_email', 'description',
|
'name', 'version', 'package', 'author', 'author_email', 'description',
|
||||||
)
|
)
|
||||||
default_columns = (
|
default_columns = (
|
||||||
'name', 'version', 'package', 'author', 'author_email', 'description',
|
'name', 'version', 'package', 'description',
|
||||||
)
|
)
|
||||||
|
@ -43,9 +43,6 @@ urlpatterns = (
|
|||||||
path('config-revisions/<int:pk>/restore/', views.ConfigRevisionRestoreView.as_view(), name='configrevision_restore'),
|
path('config-revisions/<int:pk>/restore/', views.ConfigRevisionRestoreView.as_view(), name='configrevision_restore'),
|
||||||
path('config-revisions/<int:pk>/', include(get_model_urls('core', 'configrevision'))),
|
path('config-revisions/<int:pk>/', include(get_model_urls('core', 'configrevision'))),
|
||||||
|
|
||||||
# Configuration
|
# System
|
||||||
path('config/', views.ConfigView.as_view(), name='config'),
|
path('system/', views.SystemView.as_view(), name='system'),
|
||||||
|
|
||||||
# Plugins
|
|
||||||
path('plugins/', views.PluginListView.as_view(), name='plugin_list'),
|
|
||||||
)
|
)
|
||||||
|
@ -1,14 +1,19 @@
|
|||||||
|
import json
|
||||||
|
import platform
|
||||||
|
|
||||||
|
from django import __version__ as DJANGO_VERSION
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.mixins import UserPassesTestMixin
|
from django.contrib.auth.mixins import UserPassesTestMixin
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.http import HttpResponseForbidden, Http404
|
from django.db import connection, ProgrammingError
|
||||||
|
from django.http import HttpResponse, HttpResponseForbidden, Http404
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
from django_rq.queues import get_queue_by_index, get_redis_connection
|
from django_rq.queues import get_connection, get_queue_by_index, get_redis_connection
|
||||||
from django_rq.settings import QUEUES_MAP, QUEUES_LIST
|
from django_rq.settings import QUEUES_MAP, QUEUES_LIST
|
||||||
from django_rq.utils import get_jobs, get_statistics, stop_jobs
|
from django_rq.utils import get_jobs, get_statistics, stop_jobs
|
||||||
from rq import requeue_job
|
from rq import requeue_job
|
||||||
@ -175,20 +180,6 @@ class JobBulkDeleteView(generic.BulkDeleteView):
|
|||||||
# Config Revisions
|
# Config Revisions
|
||||||
#
|
#
|
||||||
|
|
||||||
class ConfigView(generic.ObjectView):
|
|
||||||
queryset = ConfigRevision.objects.all()
|
|
||||||
|
|
||||||
def get_object(self, **kwargs):
|
|
||||||
revision_id = cache.get('config_version')
|
|
||||||
try:
|
|
||||||
return ConfigRevision.objects.get(pk=revision_id)
|
|
||||||
except ConfigRevision.DoesNotExist:
|
|
||||||
# Fall back to using the active config data if no record is found
|
|
||||||
return ConfigRevision(
|
|
||||||
data=get_config().defaults
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigRevisionListView(generic.ObjectListView):
|
class ConfigRevisionListView(generic.ObjectListView):
|
||||||
queryset = ConfigRevision.objects.all()
|
queryset = ConfigRevision.objects.all()
|
||||||
filterset = filtersets.ConfigRevisionFilterSet
|
filterset = filtersets.ConfigRevisionFilterSet
|
||||||
@ -527,21 +518,69 @@ class WorkerView(BaseRQView):
|
|||||||
# Plugins
|
# Plugins
|
||||||
#
|
#
|
||||||
|
|
||||||
class PluginListView(UserPassesTestMixin, View):
|
class SystemView(UserPassesTestMixin, View):
|
||||||
|
|
||||||
def test_func(self):
|
def test_func(self):
|
||||||
return self.request.user.is_staff
|
return self.request.user.is_staff
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
|
|
||||||
|
# System stats
|
||||||
|
psql_version = db_name = db_size = None
|
||||||
|
try:
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute("SELECT version()")
|
||||||
|
psql_version = cursor.fetchone()[0]
|
||||||
|
psql_version = psql_version.split('(')[0].strip()
|
||||||
|
cursor.execute("SELECT current_database()")
|
||||||
|
db_name = cursor.fetchone()[0]
|
||||||
|
cursor.execute(f"SELECT pg_size_pretty(pg_database_size('{db_name}'))")
|
||||||
|
db_size = cursor.fetchone()[0]
|
||||||
|
except (ProgrammingError, IndexError):
|
||||||
|
pass
|
||||||
|
stats = {
|
||||||
|
'netbox_version': settings.VERSION,
|
||||||
|
'django_version': DJANGO_VERSION,
|
||||||
|
'python_version': platform.python_version(),
|
||||||
|
'postgresql_version': psql_version,
|
||||||
|
'database_name': db_name,
|
||||||
|
'database_size': db_size,
|
||||||
|
'rq_worker_count': Worker.count(get_connection('default')),
|
||||||
|
}
|
||||||
|
|
||||||
|
# Plugins
|
||||||
plugins = [
|
plugins = [
|
||||||
# Look up app config by package name
|
# Look up app config by package name
|
||||||
apps.get_app_config(plugin.rsplit('.', 1)[-1]) for plugin in settings.PLUGINS
|
apps.get_app_config(plugin.rsplit('.', 1)[-1]) for plugin in settings.PLUGINS
|
||||||
]
|
]
|
||||||
table = tables.PluginTable(plugins, user=request.user)
|
|
||||||
table.configure(request)
|
|
||||||
|
|
||||||
return render(request, 'core/plugin_list.html', {
|
# Configuration
|
||||||
'plugins': plugins,
|
try:
|
||||||
'active_tab': 'api-tokens',
|
config = ConfigRevision.objects.get(pk=cache.get('config_version'))
|
||||||
'table': table,
|
except ConfigRevision.DoesNotExist:
|
||||||
|
# Fall back to using the active config data if no record is found
|
||||||
|
config = ConfigRevision(data=get_config().defaults)
|
||||||
|
|
||||||
|
# Raw data export
|
||||||
|
if 'export' in request.GET:
|
||||||
|
data = {
|
||||||
|
**stats,
|
||||||
|
'plugins': {
|
||||||
|
plugin.name: plugin.version for plugin in plugins
|
||||||
|
},
|
||||||
|
'config': {
|
||||||
|
k: config.data[k] for k in sorted(config.data)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
response = HttpResponse(json.dumps(data, indent=4), content_type='text/json')
|
||||||
|
response['Content-Disposition'] = 'attachment; filename="netbox.json"'
|
||||||
|
return response
|
||||||
|
|
||||||
|
plugins_table = tables.PluginTable(plugins, orderable=False)
|
||||||
|
plugins_table.configure(request)
|
||||||
|
|
||||||
|
return render(request, 'core/system.html', {
|
||||||
|
'stats': stats,
|
||||||
|
'plugins_table': plugins_table,
|
||||||
|
'config': config,
|
||||||
})
|
})
|
||||||
|
@ -420,27 +420,17 @@ ADMIN_MENU = Menu(
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MenuGroup(
|
|
||||||
label=_('Configuration'),
|
|
||||||
items=(
|
|
||||||
MenuItem(
|
|
||||||
link='core:config',
|
|
||||||
link_text=_('Current Config'),
|
|
||||||
permissions=['core.view_configrevision']
|
|
||||||
),
|
|
||||||
MenuItem(
|
|
||||||
link='core:configrevision_list',
|
|
||||||
link_text=_('Config Revisions'),
|
|
||||||
permissions=['core.view_configrevision']
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
MenuGroup(
|
MenuGroup(
|
||||||
label=_('System'),
|
label=_('System'),
|
||||||
items=(
|
items=(
|
||||||
MenuItem(
|
MenuItem(
|
||||||
link='core:plugin_list',
|
link='core:system',
|
||||||
link_text=_('Plugins')
|
link_text=_('System')
|
||||||
|
),
|
||||||
|
MenuItem(
|
||||||
|
link='core:configrevision_list',
|
||||||
|
link_text=_('Configuration History'),
|
||||||
|
permissions=['core.view_configrevision']
|
||||||
),
|
),
|
||||||
MenuItem(
|
MenuItem(
|
||||||
link='core:background_queue_list',
|
link='core:background_queue_list',
|
||||||
|
@ -32,163 +32,8 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h5 class="card-header">{% trans "Rack Elevations" %}</h5>
|
<h5 class="card-header">{% trans "Configuration Data" %}</h5>
|
||||||
<table class="table table-hover attr-table">
|
{% include 'core/inc/config_data.html' with config=config.data %}
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Default unit height" %}</th>
|
|
||||||
<td>{{ object.data.RACK_ELEVATION_DEFAULT_UNIT_HEIGHT }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Default unit width" %}</th>
|
|
||||||
<td>{{ object.data.RACK_ELEVATION_DEFAULT_UNIT_WIDTH }}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<h5 class="card-header">{% trans "Power Feeds" %}</h5>
|
|
||||||
<table class="table table-hover attr-table">
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Default voltage" %}</th>
|
|
||||||
<td>{{ object.data.POWERFEED_DEFAULT_VOLTAGE }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Default amperage" %}</th>
|
|
||||||
<td>{{ object.data.POWERFEED_DEFAULT_AMPERAGE }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Default max utilization" %}</th>
|
|
||||||
<td>{{ object.data.POWERFEED_DEFAULT_MAX_UTILIZATION }}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<h5 class="card-header">{% trans "IPAM" %}</h5>
|
|
||||||
<table class="table table-hover attr-table">
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Enforce global unique" %}</th>
|
|
||||||
<td>{{ object.data.ENFORCE_GLOBAL_UNIQUE }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Prefer IPv4" %}</th>
|
|
||||||
<td>{{ object.data.PREFER_IPV4 }}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<h5 class="card-header">{% trans "Security" %}</h5>
|
|
||||||
<table class="table table-hover attr-table">
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Allowed URL schemes" %}</th>
|
|
||||||
<td>{{ object.data.ALLOWED_URL_SCHEMES|join:", "|placeholder }}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<h5 class="card-header">{% trans "Banners" %}</h5>
|
|
||||||
<table class="table table-hover attr-table">
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Login banner" %}</th>
|
|
||||||
<td>{{ object.data.BANNER_LOGIN }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Maintenance banner" %}</th>
|
|
||||||
<td>{{ object.data.BANNER_MAINTENANCE }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Top banner" %}</th>
|
|
||||||
<td>{{ object.data.BANNER_TOP }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Bottom banner" %}</th>
|
|
||||||
<td>{{ object.data.BANNER_BOTTOM }}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<h5 class="card-header">{% trans "Pagination" %}</h5>
|
|
||||||
<table class="table table-hover attr-table">
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Paginate count" %}</th>
|
|
||||||
<td>{{ object.data.PAGINATE_COUNT }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Max page size" %}</th>
|
|
||||||
<td>{{ object.data.MAX_PAGE_SIZE }}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<h5 class="card-header">{% trans "Validation" %}</h5>
|
|
||||||
<table class="table table-hover attr-table">
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Custom validators" %}</th>
|
|
||||||
{% if object.data.CUSTOM_VALIDATORS %}
|
|
||||||
<td class="font-monospace">
|
|
||||||
<pre>{{ object.data.CUSTOM_VALIDATORS|json }}</pre>
|
|
||||||
</td>
|
|
||||||
{% else %}
|
|
||||||
<td>{{ ''|placeholder }}</td>
|
|
||||||
{% endif %}
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Protection rules" %}</th>
|
|
||||||
{% if object.data.PROTECTION_RULES %}
|
|
||||||
<td>
|
|
||||||
<pre>{{ object.data.PROTECTION_RULES|json }}</pre>
|
|
||||||
</td>
|
|
||||||
{% else %}
|
|
||||||
<td>{{ ''|placeholder }}</td>
|
|
||||||
{% endif %}
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<h5 class="card-header">{% trans "User Preferences" %}</h5>
|
|
||||||
<table class="table table-hover attr-table">
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Default user preferences" %}</th>
|
|
||||||
{% if object.data.DEFAULT_USER_PREFERENCES %}
|
|
||||||
<td>
|
|
||||||
<pre>{{ object.data.DEFAULT_USER_PREFERENCES|json }}</pre>
|
|
||||||
</td>
|
|
||||||
{% else %}
|
|
||||||
<td>{{ ''|placeholder }}</td>
|
|
||||||
{% endif %}
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<h5 class="card-header">{% trans "Miscellaneous" %}</h5>
|
|
||||||
<table class="table table-hover attr-table">
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Maintenance mode" %}</th>
|
|
||||||
<td>{{ object.data.MAINTENANCE_MODE }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "GraphQL enabled" %}</th>
|
|
||||||
<td>{{ object.data.GRAPHQL_ENABLED }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Changelog retention" %}</th>
|
|
||||||
<td>{{ object.data.CHANGELOG_RETENTION }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Job retention" %}</th>
|
|
||||||
<td>{{ object.data.JOB_RETENTION }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">{% trans "Maps URL" %}</th>
|
|
||||||
<td>{{ object.data.MAPS_URL }}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
149
netbox/templates/core/inc/config_data.html
Normal file
149
netbox/templates/core/inc/config_data.html
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
<table class="table table-hover attr-table">
|
||||||
|
|
||||||
|
{# Rack elevations #}
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="bg-secondary-subtle fs-5 fw-bold border-0 py-1">{% trans "Rack elevations" %}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="ps-3">{% trans "Default unit height" %}</th>
|
||||||
|
<td>{{ config.RACK_ELEVATION_DEFAULT_UNIT_HEIGHT }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="border-0 ps-3">{% trans "Default unit width" %}</th>
|
||||||
|
<td class="border-0">{{ config.RACK_ELEVATION_DEFAULT_UNIT_WIDTH }}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{# Power feeds #}
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="bg-secondary-subtle fs-5 fw-bold border-0 py-1">{% trans "Power feeds" %}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="ps-3">{% trans "Default voltage" %}</th>
|
||||||
|
<td>{{ config.POWERFEED_DEFAULT_VOLTAGE }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="ps-3">{% trans "Default amperage" %}</th>
|
||||||
|
<td>{{ config.POWERFEED_DEFAULT_AMPERAGE }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="border-0 ps-3">{% trans "Default max utilization" %}</th>
|
||||||
|
<td class="border-0">{{ config.POWERFEED_DEFAULT_MAX_UTILIZATION }}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{# IPAM #}
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="bg-secondary-subtle fs-5 fw-bold border-0 py-1">{% trans "IPAM" %}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="ps-3">{% trans "Enforce global unique" %}</th>
|
||||||
|
<td>{% checkmark config.ENFORCE_GLOBAL_UNIQUE %}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="border-0 ps-3">{% trans "Prefer IPv4" %}</th>
|
||||||
|
<td class="border-0">{% checkmark config.PREFER_IPV4 %}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{# Security #}
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="bg-secondary-subtle fs-5 fw-bold border-0 py-1">{% trans "Security" %}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="border-0 ps-3">{% trans "Allowed URL schemes" %}</th>
|
||||||
|
<td class="border-0">{{ config.ALLOWED_URL_SCHEMES|join:", "|placeholder }}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{# Banners #}
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="bg-secondary-subtle fs-5 fw-bold border-0 py-1">{% trans "Banners" %}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="ps-3">{% trans "Login banner" %}</th>
|
||||||
|
<td>{{ config.BANNER_LOGIN|placeholder }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="ps-3">{% trans "Maintenance banner" %}</th>
|
||||||
|
<td>{{ config.BANNER_MAINTENANCE|placeholder }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="ps-3">{% trans "Top banner" %}</th>
|
||||||
|
<td>{{ config.BANNER_TOP|placeholder }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="border-0 ps-3">{% trans "Bottom banner" %}</th>
|
||||||
|
<td class="border-0">{{ config.BANNER_BOTTOM|placeholder }}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{# Pagination #}
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="bg-secondary-subtle fs-5 fw-bold border-0 py-1">{% trans "Pagination" %}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="ps-3">{% trans "Paginate count" %}</th>
|
||||||
|
<td>{{ config.PAGINATE_COUNT }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="border-0 ps-3">{% trans "Max page size" %}</th>
|
||||||
|
<td class="border-0">{{ config.MAX_PAGE_SIZE }}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{# Validation #}
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="bg-secondary-subtle fs-5 fw-bold border-0 py-1">{% trans "Validation" %}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="ps-3">{% trans "Custom validators" %}</th>
|
||||||
|
{% if config.CUSTOM_VALIDATORS %}
|
||||||
|
<td><pre>{{ config.CUSTOM_VALIDATORS|json }}</pre></td>
|
||||||
|
{% else %}
|
||||||
|
<td>{{ ''|placeholder }}</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="border-0 ps-3">{% trans "Protection rules" %}</th>
|
||||||
|
{% if config.PROTECTION_RULES %}
|
||||||
|
<td class="border-0"><pre>{{ config.PROTECTION_RULES|json }}</pre></td>
|
||||||
|
{% else %}
|
||||||
|
<td class="border-0">{{ ''|placeholder }}</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{# User Preferences #}
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="bg-secondary-subtle fs-5 fw-bold border-0 py-1">{% trans "User preferences" %}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="border-0 ps-3">{% trans "Default preferences" %}</th>
|
||||||
|
{% if config.DEFAULT_USER_PREFERENCES %}
|
||||||
|
<td class="border-0"><pre>{{ config.DEFAULT_USER_PREFERENCES|json }}</pre></td>
|
||||||
|
{% else %}
|
||||||
|
<td class="border-0">{{ ''|placeholder }}</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{# Miscellaneous #}
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="bg-secondary-subtle fs-5 fw-bold border-0 py-1">{% trans "Miscellaneous" %}</td>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="ps-3">{% trans "Maintenance mode" %}</th>
|
||||||
|
<td>{% checkmark config.MAINTENANCE_MODE %}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="ps-3">{% trans "GraphQL enabled" %}</th>
|
||||||
|
<td>{% checkmark config.GRAPHQL_ENABLED %}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="ps-3">{% trans "Changelog retention" %}</th>
|
||||||
|
<td>{{ config.CHANGELOG_RETENTION }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="ps-3">{% trans "Job retention" %}</th>
|
||||||
|
<td>{{ config.JOB_RETENTION }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="border-0 ps-3">{% trans "Maps URL" %}</th>
|
||||||
|
<td class="border-0">{{ config.MAPS_URL }}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
@ -1,36 +0,0 @@
|
|||||||
{% extends 'generic/_base.html' %}
|
|
||||||
{% load buttons %}
|
|
||||||
{% load helpers %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load render_table from django_tables2 %}
|
|
||||||
|
|
||||||
{% block title %}{% trans "Plugins" %}{% endblock %}
|
|
||||||
|
|
||||||
{% block tabs %}
|
|
||||||
<ul class="nav nav-tabs px-3">
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<a class="nav-link active" role="tab">{% trans "Plugins" %}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
{% endblock tabs %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col-auto ms-auto d-print-none">
|
|
||||||
{# Table configuration button #}
|
|
||||||
<div class="table-configure input-group">
|
|
||||||
<button type="button" data-bs-toggle="modal" title="{% trans "Configure Table" %}" data-bs-target="#ObjectTable_config" class="btn">
|
|
||||||
<i class="mdi mdi-cog"></i> {% trans "Configure Table" %}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
{% render_table table %}
|
|
||||||
</div>
|
|
||||||
{% endblock content %}
|
|
||||||
|
|
||||||
{% block modals %}
|
|
||||||
{% table_config_form table table_name="ObjectTable" %}
|
|
||||||
{% endblock modals %}
|
|
92
netbox/templates/core/system.html
Normal file
92
netbox/templates/core/system.html
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
{% extends 'generic/_base.html' %}
|
||||||
|
{% load buttons %}
|
||||||
|
{% load helpers %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load render_table from django_tables2 %}
|
||||||
|
|
||||||
|
{% block title %}{% trans "System" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block controls %}
|
||||||
|
<a href="?export=true" class="btn btn-purple">
|
||||||
|
<i class="mdi mdi-download"></i> {% trans "Export" %}
|
||||||
|
</a>
|
||||||
|
{% endblock controls %}
|
||||||
|
|
||||||
|
{% block tabs %}
|
||||||
|
<ul class="nav nav-tabs px-3">
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<a class="nav-link active" role="tab">{% trans "Status" %}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{% endblock tabs %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{# System status #}
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<div class="card">
|
||||||
|
<h5 class="card-header">{% trans "System Status" %}</h5>
|
||||||
|
<table class="table table-hover attr-table">
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "NetBox version" %}</th>
|
||||||
|
<td>{{ stats.netbox_version }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "Django version" %}</th>
|
||||||
|
<td>{{ stats.django_version }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "PotsgreSQL version" %}</th>
|
||||||
|
<td>{{ stats.postgresql_version }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "Database name" %}</th>
|
||||||
|
<td>{{ stats.database_name }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "Database size" %}</th>
|
||||||
|
<td>
|
||||||
|
{% if stats.database_size %}
|
||||||
|
{{ stats.database_size }}
|
||||||
|
{% else %}
|
||||||
|
<span class="text-muted">{% trans "Unavailable" %}</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "RQ workers" %}</th>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'core:background_queue_list' %}">{{ stats.rq_worker_count }}</a>
|
||||||
|
({% trans "default queue" %})
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "System time" %}</th>
|
||||||
|
<td>{% now 'Y-m-d H:i:s T' %}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# Plugins #}
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col col-md-12">
|
||||||
|
<div class="card">
|
||||||
|
<h5 class="card-header">{% trans "Plugins" %}</h5>
|
||||||
|
{% render_table plugins_table %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# Configuration #}
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col col-md-12">
|
||||||
|
<div class="card">
|
||||||
|
<h5 class="card-header">{% trans "Current Configuration" %}</h5>
|
||||||
|
{% include 'core/inc/config_data.html' with config=config.data %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
Reference in New Issue
Block a user