14731 review changes

This commit is contained in:
Arthur Hanson 2024-07-17 15:21:32 +07:00
parent 657b12cc3e
commit 7594ecc790
4 changed files with 90 additions and 76 deletions

View File

@ -32,6 +32,8 @@ class Plugin:
tag_line: str = ''
description_short: str = ''
author: str = ''
homepage_url: str = ''
license_type: str = ''
created: datetime.datetime = None
updated: datetime.datetime = None
is_local: bool = False
@ -41,7 +43,8 @@ class Plugin:
versions: list[PluginVersion] = field(default_factory=list)
def get_local_plugins(plugins):
def get_local_plugins():
plugins = {}
for plugin_name in settings.PLUGINS:
plugin = importlib.import_module(plugin_name)
plugin_config: PluginConfig = plugin.config
@ -62,20 +65,20 @@ def get_local_plugins(plugins):
return plugins
def get_catalog_plugins(plugins):
url = 'https://api.netbox.oss.netboxlabs.com/v1/plugins'
def get_catalog_plugins():
session = requests.Session()
plugins = {}
def get_pages():
# TODO: pagintation is curently broken in API
payload = {'page': '1', 'per_page': '50'}
first_page = session.get(url, params=payload).json()
first_page = session.get(settings.PLUGIN_CATALOG_URL, params=payload).json()
yield first_page
num_pages = first_page['metadata']['pagination']['last_page']
for page in range(2, num_pages + 1):
payload['page'] = page
next_page = session.get(url, params=payload).json()
next_page = session.get(settings.PLUGIN_CATALOG_URL, params=payload).json()
yield next_page
for page in get_pages():
@ -96,39 +99,43 @@ def get_catalog_plugins(plugins):
is_netboxlabs_supported=version['is_netboxlabs_supported'],
)
)
versions = sorted(versions, key=lambda x: x.date, reverse=True)
if data['slug'] in plugins:
plugins[data['slug']].is_local = False
plugins[data['slug']].is_certified = data['release_latest']['is_certified']
plugins[data['slug']].description_short = data['description_short']
else:
plugins[data['slug']] = Plugin(
slug=data['slug'],
config_name=data['config_name'],
name=data['title_short'],
title_long=data['title_long'],
tag_line=data['tag_line'],
description_short=data['description_short'],
author=data['author']['name'] or _('Unknown Author'),
created=datetime_from_timestamp(data['created_at']),
updated=datetime_from_timestamp(data['updated_at']),
is_local=False,
is_installed=False,
is_certified=data['release_latest']['is_certified'],
is_community=not data['release_latest']['is_certified'],
versions=versions,
)
plugins[data['slug']] = Plugin(
slug=data['slug'],
config_name=data['config_name'],
name=data['title_short'],
title_long=data['title_long'],
tag_line=data['tag_line'],
description_short=data['description_short'],
author=data['author']['name'] or _('Unknown Author'),
homepage_url=data['homepage_url'],
license_type=data['license_type'],
created=datetime_from_timestamp(data['created_at']),
updated=datetime_from_timestamp(data['updated_at']),
is_local=False,
is_installed=False,
is_certified=data['release_latest']['is_certified'],
is_community=not data['release_latest']['is_certified'],
versions=versions,
)
return plugins
def get_plugins():
if plugins := cache.get('plugins-catalog-feed'):
return plugins
local_plugins = get_local_plugins()
catalog_plugins = cache.get('plugins-catalog-feed')
if not catalog_plugins:
catalog_plugins = get_catalog_plugins()
cache.set('plugins-catalog-feed', catalog_plugins, 3600)
plugins = {}
plugins = get_local_plugins(plugins)
plugins = get_catalog_plugins(plugins)
plugins = catalog_plugins
for k, v in local_plugins.items():
if k in plugins:
plugins[k].is_local = True
plugins[k].is_installed = True
else:
plugins[k] = v
cache.set('plugins-catalog-feed', plugins, 3600)
return plugins

View File

@ -617,12 +617,6 @@ class SystemView(UserPassesTestMixin, View):
'rq_worker_count': Worker.count(get_connection('default')),
}
# Plugins
plugins = [
# Look up app config by package name
apps.get_app_config(plugin.rsplit('.', 1)[-1]) for plugin in settings.PLUGINS
]
# Configuration
try:
config = ConfigRevision.objects.get(pk=cache.get('config_version'))
@ -634,9 +628,6 @@ class SystemView(UserPassesTestMixin, View):
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)
},
@ -664,10 +655,18 @@ class PluginListView(UserPassesTestMixin, View):
q = request.GET.get('q', None)
plugins = get_plugins()
plugins = plugins.values()
if q:
plugins = [v for k, v in plugins.items() if q.casefold() in v['name'].casefold()]
else:
plugins = plugins.values()
plugins = [obj for obj in plugins if q.casefold() in obj.name.casefold()]
# Sort order should be:
# Installed plugins
# Certified catalog plugins
# Remaining catalog plugins
# With alphabetical sort within each traunch.
plugins = sorted(plugins, key=lambda x: x.name, reverse=False)
plugins = sorted(plugins, key=lambda x: x.is_certified, reverse=True)
plugins = sorted(plugins, key=lambda x: x.is_installed, reverse=True)
table = CatalogPluginTable(plugins, user=request.user)
table.configure(request)

View File

@ -769,6 +769,8 @@ STRAWBERRY_DJANGO = {
# Plugins
#
PLUGIN_CATALOG_URL = 'https://api.netbox.oss.netboxlabs.com/v1/plugins'
# Register any configured plugins
for plugin_name in PLUGINS:
try:

View File

@ -15,6 +15,8 @@
{% block subtitle %}
<div class="text-secondary fs-5">
{{ plugin.tag_line }}
<a href="{{ plugin.homepage.url }}" target="_blank">Learn more <i class="mdi mdi-launch"></i></a><br />
<strong>License:</strong> {{ plugin.license_type }}
</div>
{% endblock subtitle %}
@ -33,16 +35,18 @@ From
</a>
</li>
{% if not plugin.is_local %}
<li class="nav-item" role="presentation">
<button class="nav-link" id="version-history-tab" data-bs-toggle="tab" data-bs-target="#version-history" type="button" role="tab" aria-controls="object-list" aria-selected="false">
{% trans "Version history" %}
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="install-tab" data-bs-toggle="tab" data-bs-target="#install" type="button" role="tab" aria-controls="object-list" aria-selected="false">
{% trans "Install" %}
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="version-history-tab" data-bs-toggle="tab" data-bs-target="#version-history" type="button" role="tab" aria-controls="object-list" aria-selected="false">
{% trans "Version history" %}
</button>
</li>
{% if plugin.is_community %}
<li class="nav-item" role="presentation">
<button class="nav-link" id="install-tab" data-bs-toggle="tab" data-bs-target="#install" type="button" role="tab" aria-controls="object-list" aria-selected="false">
{% trans "Install" %}
</button>
</li>
{% endif %}
{% endif %}
</ul>
@ -51,23 +55,24 @@ From
{% block content %}
<div class="tab-pane show active" id="overview" role="tabpanel" aria-labelledby="overview-tab">
{{ plugin.description_short }}
{{ plugin.description_short|markdown }}
</div>
{% if not plugin.is_local %}
<div class="tab-pane" id="version-history" role="tabpanel" aria-labelledby="version-history-tab">
<div class="card">
<div class="tab-pane" id="version-history" role="tabpanel" aria-labelledby="version-history-tab">
<div class="card">
<div class="htmx-container table-responsive" id="object_list">
{% include 'htmx/table.html' %}
<div class="htmx-container table-responsive" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
</div>
</div>
<div class="tab-pane" id="install" role="tabpanel" aria-labelledby="install-tab">
<p>You can install this plugin from the command line with PyPi.</p>
<p>The following commands may be helpful; always refer to the plugin's own documentation and the Installing a Plugin unit of the NetBox documentation.</p>
<p>1. Enter the NetBox virtual environment and install the plugin package:</p>
{% if plugin.is_community %}
<div class="tab-pane" id="install" role="tabpanel" aria-labelledby="install-tab">
<p>You can install this plugin from the command line with PyPi.</p>
<p>The following commands may be helpful; always refer to <a href="{{ plugin.homepage_url }}" target="_blank">the plugin's own documentation <i class="mdi mdi-launch"></i></a> and the <a href="https://netboxlabs.com/docs/netbox/en/stable/plugins/installation/" target="_blank">Installing a Plugin unit <i class="mdi mdi-launch"></i></a> of the NetBox documentation.</p>
<p>1. Enter the NetBox virtual environment and install the plugin package:</p>
<pre class="block"><code>
<pre class="block"><code>
source /opt/netbox/venv/bin/activate
pip install {{ plugin.slug }}
</code></pre>
@ -76,16 +81,17 @@ pip install {{ plugin.slug }}
PLUGINS=
"{{ plugin.config_name }}",
]
</code></pre>
<p>3. Still from the NetBox virtual environment, run database migrations and collect static files:</p>
<pre class="block"><code>
python3 /opt/netbox/netbox/netbox/manage.py migrate
python3 /opt/netbox/netbox/netbox/manage.py collectstatic
</code></pre>
<p>4. Restart the NetBox services to complete the plugin installation:</p>
<pre class="block"><code>
sudo systemctl restart netbox netbox-rq
</code></pre>
</div>
</code></pre>
<p>3. Still from the NetBox virtual environment, run database migrations and collect static files:</p>
<pre class="block"><code>
python3 /opt/netbox/netbox/netbox/manage.py migrate
python3 /opt/netbox/netbox/netbox/manage.py collectstatic
</code></pre>
<p>4. Restart the NetBox services to complete the plugin installation:</p>
<pre class="block"><code>
sudo systemctl restart netbox netbox-rq
</code></pre>
</div>
{% endif %}
{% endif %}
{% endblock content %}