mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-08 08:38:16 -06:00
14731 review changes
This commit is contained in:
parent
657b12cc3e
commit
7594ecc790
@ -32,6 +32,8 @@ class Plugin:
|
|||||||
tag_line: str = ''
|
tag_line: str = ''
|
||||||
description_short: str = ''
|
description_short: str = ''
|
||||||
author: str = ''
|
author: str = ''
|
||||||
|
homepage_url: str = ''
|
||||||
|
license_type: str = ''
|
||||||
created: datetime.datetime = None
|
created: datetime.datetime = None
|
||||||
updated: datetime.datetime = None
|
updated: datetime.datetime = None
|
||||||
is_local: bool = False
|
is_local: bool = False
|
||||||
@ -41,7 +43,8 @@ class Plugin:
|
|||||||
versions: list[PluginVersion] = field(default_factory=list)
|
versions: list[PluginVersion] = field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
def get_local_plugins(plugins):
|
def get_local_plugins():
|
||||||
|
plugins = {}
|
||||||
for plugin_name in settings.PLUGINS:
|
for plugin_name in settings.PLUGINS:
|
||||||
plugin = importlib.import_module(plugin_name)
|
plugin = importlib.import_module(plugin_name)
|
||||||
plugin_config: PluginConfig = plugin.config
|
plugin_config: PluginConfig = plugin.config
|
||||||
@ -62,20 +65,20 @@ def get_local_plugins(plugins):
|
|||||||
return plugins
|
return plugins
|
||||||
|
|
||||||
|
|
||||||
def get_catalog_plugins(plugins):
|
def get_catalog_plugins():
|
||||||
url = 'https://api.netbox.oss.netboxlabs.com/v1/plugins'
|
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
|
plugins = {}
|
||||||
|
|
||||||
def get_pages():
|
def get_pages():
|
||||||
# TODO: pagintation is curently broken in API
|
# TODO: pagintation is curently broken in API
|
||||||
payload = {'page': '1', 'per_page': '50'}
|
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
|
yield first_page
|
||||||
num_pages = first_page['metadata']['pagination']['last_page']
|
num_pages = first_page['metadata']['pagination']['last_page']
|
||||||
|
|
||||||
for page in range(2, num_pages + 1):
|
for page in range(2, num_pages + 1):
|
||||||
payload['page'] = page
|
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
|
yield next_page
|
||||||
|
|
||||||
for page in get_pages():
|
for page in get_pages():
|
||||||
@ -96,39 +99,43 @@ def get_catalog_plugins(plugins):
|
|||||||
is_netboxlabs_supported=version['is_netboxlabs_supported'],
|
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']] = Plugin(
|
||||||
plugins[data['slug']].is_local = False
|
slug=data['slug'],
|
||||||
plugins[data['slug']].is_certified = data['release_latest']['is_certified']
|
config_name=data['config_name'],
|
||||||
plugins[data['slug']].description_short = data['description_short']
|
name=data['title_short'],
|
||||||
else:
|
title_long=data['title_long'],
|
||||||
plugins[data['slug']] = Plugin(
|
tag_line=data['tag_line'],
|
||||||
slug=data['slug'],
|
description_short=data['description_short'],
|
||||||
config_name=data['config_name'],
|
author=data['author']['name'] or _('Unknown Author'),
|
||||||
name=data['title_short'],
|
homepage_url=data['homepage_url'],
|
||||||
title_long=data['title_long'],
|
license_type=data['license_type'],
|
||||||
tag_line=data['tag_line'],
|
created=datetime_from_timestamp(data['created_at']),
|
||||||
description_short=data['description_short'],
|
updated=datetime_from_timestamp(data['updated_at']),
|
||||||
author=data['author']['name'] or _('Unknown Author'),
|
is_local=False,
|
||||||
created=datetime_from_timestamp(data['created_at']),
|
is_installed=False,
|
||||||
updated=datetime_from_timestamp(data['updated_at']),
|
is_certified=data['release_latest']['is_certified'],
|
||||||
is_local=False,
|
is_community=not data['release_latest']['is_certified'],
|
||||||
is_installed=False,
|
versions=versions,
|
||||||
is_certified=data['release_latest']['is_certified'],
|
)
|
||||||
is_community=not data['release_latest']['is_certified'],
|
|
||||||
versions=versions,
|
|
||||||
)
|
|
||||||
|
|
||||||
return plugins
|
return plugins
|
||||||
|
|
||||||
|
|
||||||
def get_plugins():
|
def get_plugins():
|
||||||
if plugins := cache.get('plugins-catalog-feed'):
|
local_plugins = get_local_plugins()
|
||||||
return 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 = catalog_plugins
|
||||||
plugins = get_local_plugins(plugins)
|
for k, v in local_plugins.items():
|
||||||
plugins = get_catalog_plugins(plugins)
|
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
|
return plugins
|
||||||
|
@ -617,12 +617,6 @@ class SystemView(UserPassesTestMixin, View):
|
|||||||
'rq_worker_count': Worker.count(get_connection('default')),
|
'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
|
# Configuration
|
||||||
try:
|
try:
|
||||||
config = ConfigRevision.objects.get(pk=cache.get('config_version'))
|
config = ConfigRevision.objects.get(pk=cache.get('config_version'))
|
||||||
@ -634,9 +628,6 @@ class SystemView(UserPassesTestMixin, View):
|
|||||||
if 'export' in request.GET:
|
if 'export' in request.GET:
|
||||||
data = {
|
data = {
|
||||||
**stats,
|
**stats,
|
||||||
'plugins': {
|
|
||||||
plugin.name: plugin.version for plugin in plugins
|
|
||||||
},
|
|
||||||
'config': {
|
'config': {
|
||||||
k: config.data[k] for k in sorted(config.data)
|
k: config.data[k] for k in sorted(config.data)
|
||||||
},
|
},
|
||||||
@ -664,10 +655,18 @@ class PluginListView(UserPassesTestMixin, View):
|
|||||||
q = request.GET.get('q', None)
|
q = request.GET.get('q', None)
|
||||||
|
|
||||||
plugins = get_plugins()
|
plugins = get_plugins()
|
||||||
|
plugins = plugins.values()
|
||||||
if q:
|
if q:
|
||||||
plugins = [v for k, v in plugins.items() if q.casefold() in v['name'].casefold()]
|
plugins = [obj for obj in plugins if q.casefold() in obj.name.casefold()]
|
||||||
else:
|
|
||||||
plugins = plugins.values()
|
# 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 = CatalogPluginTable(plugins, user=request.user)
|
||||||
table.configure(request)
|
table.configure(request)
|
||||||
|
@ -769,6 +769,8 @@ STRAWBERRY_DJANGO = {
|
|||||||
# Plugins
|
# Plugins
|
||||||
#
|
#
|
||||||
|
|
||||||
|
PLUGIN_CATALOG_URL = 'https://api.netbox.oss.netboxlabs.com/v1/plugins'
|
||||||
|
|
||||||
# Register any configured plugins
|
# Register any configured plugins
|
||||||
for plugin_name in PLUGINS:
|
for plugin_name in PLUGINS:
|
||||||
try:
|
try:
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
{% block subtitle %}
|
{% block subtitle %}
|
||||||
<div class="text-secondary fs-5">
|
<div class="text-secondary fs-5">
|
||||||
{{ plugin.tag_line }}
|
{{ 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>
|
</div>
|
||||||
{% endblock subtitle %}
|
{% endblock subtitle %}
|
||||||
|
|
||||||
@ -33,16 +35,18 @@ From
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% if not plugin.is_local %}
|
{% if not plugin.is_local %}
|
||||||
<li class="nav-item" role="presentation">
|
<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">
|
<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" %}
|
{% trans "Version history" %}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item" role="presentation">
|
{% if plugin.is_community %}
|
||||||
<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">
|
<li class="nav-item" role="presentation">
|
||||||
{% trans "Install" %}
|
<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">
|
||||||
</button>
|
{% trans "Install" %}
|
||||||
</li>
|
</button>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@ -51,23 +55,24 @@ From
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="tab-pane show active" id="overview" role="tabpanel" aria-labelledby="overview-tab">
|
<div class="tab-pane show active" id="overview" role="tabpanel" aria-labelledby="overview-tab">
|
||||||
{{ plugin.description_short }}
|
{{ plugin.description_short|markdown }}
|
||||||
</div>
|
</div>
|
||||||
{% if not plugin.is_local %}
|
{% if not plugin.is_local %}
|
||||||
<div class="tab-pane" id="version-history" role="tabpanel" aria-labelledby="version-history-tab">
|
<div class="tab-pane" id="version-history" role="tabpanel" aria-labelledby="version-history-tab">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
|
||||||
<div class="htmx-container table-responsive" id="object_list">
|
<div class="htmx-container table-responsive" id="object_list">
|
||||||
{% include 'htmx/table.html' %}
|
{% include 'htmx/table.html' %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% if plugin.is_community %}
|
||||||
<div class="tab-pane" id="install" role="tabpanel" aria-labelledby="install-tab">
|
<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>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>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>
|
<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
|
source /opt/netbox/venv/bin/activate
|
||||||
pip install {{ plugin.slug }}
|
pip install {{ plugin.slug }}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@ -76,16 +81,17 @@ pip install {{ plugin.slug }}
|
|||||||
PLUGINS=[
|
PLUGINS=[
|
||||||
"{{ plugin.config_name }}",
|
"{{ plugin.config_name }}",
|
||||||
]
|
]
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<p>3. Still from the NetBox virtual environment, run database migrations and collect static files:</p>
|
<p>3. Still from the NetBox virtual environment, run database migrations and collect static files:</p>
|
||||||
<pre class="block"><code>
|
<pre class="block"><code>
|
||||||
python3 /opt/netbox/netbox/netbox/manage.py migrate
|
python3 /opt/netbox/netbox/netbox/manage.py migrate
|
||||||
python3 /opt/netbox/netbox/netbox/manage.py collectstatic
|
python3 /opt/netbox/netbox/netbox/manage.py collectstatic
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<p>4. Restart the NetBox services to complete the plugin installation:</p>
|
<p>4. Restart the NetBox services to complete the plugin installation:</p>
|
||||||
<pre class="block"><code>
|
<pre class="block"><code>
|
||||||
sudo systemctl restart netbox netbox-rq
|
sudo systemctl restart netbox netbox-rq
|
||||||
</code></pre>
|
</code></pre>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
Loading…
Reference in New Issue
Block a user