Unify api serializers (#16)
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
COMPOSE_PATH_SEPARATOR=:
|
||||
COMPOSE_FILE=ci/docker-compose.yml:ci/docker-compose.override.yml
|
||||
COMPOSE_FILE=ci/docker-compose.yml:ci/docker-compose.ci.yml
|
||||
COMPOSE_PROJECT_NAME=netbox-docker
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
name: Docker Image CI
|
||||
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -15,5 +20,17 @@ jobs:
|
||||
# clearcache is provided by Django extras, which is not loaded if netbox-slm cannot be loaded
|
||||
run: docker compose run netbox sh -c "/opt/netbox/venv/bin/python manage.py clearcache"
|
||||
|
||||
- name: Run Django tests for netbox_slm
|
||||
run: docker compose run netbox sh -c "/opt/netbox/venv/bin/python manage.py test netbox_slm"
|
||||
- name: Run Django tests with coverage for netbox_slm
|
||||
run: |
|
||||
chmod go+w ci/reports
|
||||
docker compose run netbox sh -c " \
|
||||
/opt/netbox/venv/bin/coverage run --source='netbox_slm' manage.py test netbox_slm && \
|
||||
/opt/netbox/venv/bin/coverage report --fail-under=0 && \
|
||||
/opt/netbox/venv/bin/coverage xml -o /ci/reports/coverage.xml"
|
||||
|
||||
- name: Sonarcloud scan
|
||||
if: env.SONAR_TOKEN != null
|
||||
uses: sonarsource/sonarcloud-github-action@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
|
||||
@@ -6,4 +6,6 @@
|
||||
**/.vscode
|
||||
**/dist
|
||||
**/netbox_slm.egg-info
|
||||
ci/docker-compose.override.yml
|
||||
ci/reports
|
||||
out/production
|
||||
|
||||
+3
-2
@@ -1,3 +1,4 @@
|
||||
include ../LICENSE
|
||||
include ../README.rst
|
||||
recursive-include netbox_slm/templates *
|
||||
include ../README.md
|
||||
include ../SECURITY.md
|
||||
recursive-include netbox_slm/templates *
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
FROM netboxcommunity/netbox:v3.4.7
|
||||
|
||||
RUN mkdir /ci && chmod go+w /ci
|
||||
COPY ../ci/requirements_ci.txt /ci/
|
||||
RUN pip install -r /ci/requirements_ci.txt
|
||||
|
||||
COPY ../netbox_slm /opt/netbox/netbox/netbox_slm
|
||||
|
||||
@@ -2,3 +2,10 @@ PLUGINS = ['netbox_slm']
|
||||
DEBUG = True
|
||||
SECRET_KEY = 'dummy'
|
||||
DEVELOPER = True
|
||||
PLUGINS_CONFIG = {
|
||||
'netbox_slm': dict(
|
||||
TEST_RUNNER='xmlrunner.extra.djangotestrunner.XMLTestRunner',
|
||||
TEST_OUTPUT_DIR='/ci/reports/',
|
||||
TEST_OUTPUT_FILE_NAME='junit.xml',
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
####
|
||||
## This file contains extra configuration options that can't be configured
|
||||
## directly through environment variables.
|
||||
## All vairables set here overwrite any existing found in ldap_config.py
|
||||
####
|
||||
|
||||
# # This Python script inherits all the imports from ldap_config.py
|
||||
# from django_auth_ldap.config import LDAPGroupQuery # Imported since not in ldap_config.py
|
||||
|
||||
# # Sets a base requirement of membetship to netbox-user-ro, netbox-user-rw, or netbox-user-admin.
|
||||
# AUTH_LDAP_REQUIRE_GROUP = (
|
||||
# LDAPGroupQuery("cn=netbox-user-ro,ou=groups,dc=example,dc=com")
|
||||
# | LDAPGroupQuery("cn=netbox-user-rw,ou=groups,dc=example,dc=com")
|
||||
# | LDAPGroupQuery("cn=netbox-user-admin,ou=groups,dc=example,dc=com")
|
||||
# )
|
||||
|
||||
# # Sets LDAP Flag groups variables with example.
|
||||
# AUTH_LDAP_USER_FLAGS_BY_GROUP = {
|
||||
# "is_staff": (
|
||||
# LDAPGroupQuery("cn=netbox-user-ro,ou=groups,dc=example,dc=com")
|
||||
# | LDAPGroupQuery("cn=netbox-user-rw,ou=groups,dc=example,dc=com")
|
||||
# | LDAPGroupQuery("cn=netbox-user-admin,ou=groups,dc=example,dc=com")
|
||||
# ),
|
||||
# "is_superuser": "cn=netbox-user-admin,ou=groups,dc=example,dc=com",
|
||||
# }
|
||||
|
||||
# # Sets LDAP Mirror groups variables with example groups
|
||||
# AUTH_LDAP_MIRROR_GROUPS = ["netbox-user-ro", "netbox-user-rw", "netbox-user-admin"]
|
||||
@@ -1,90 +0,0 @@
|
||||
from importlib import import_module
|
||||
from os import environ
|
||||
|
||||
import ldap
|
||||
from django_auth_ldap.config import LDAPSearch
|
||||
|
||||
|
||||
# Read secret from file
|
||||
def _read_secret(secret_name, default=None):
|
||||
try:
|
||||
f = open('/run/secrets/' + secret_name, 'r', encoding='utf-8')
|
||||
except EnvironmentError:
|
||||
return default
|
||||
else:
|
||||
with f:
|
||||
return f.readline().strip()
|
||||
|
||||
# Import and return the group type based on string name
|
||||
def _import_group_type(group_type_name):
|
||||
mod = import_module('django_auth_ldap.config')
|
||||
try:
|
||||
return getattr(mod, group_type_name)()
|
||||
except:
|
||||
return None
|
||||
|
||||
# Server URI
|
||||
AUTH_LDAP_SERVER_URI = environ.get('AUTH_LDAP_SERVER_URI', '')
|
||||
|
||||
# The following may be needed if you are binding to Active Directory.
|
||||
AUTH_LDAP_CONNECTION_OPTIONS = {
|
||||
ldap.OPT_REFERRALS: 0
|
||||
}
|
||||
|
||||
# Set the DN and password for the NetBox service account.
|
||||
AUTH_LDAP_BIND_DN = environ.get('AUTH_LDAP_BIND_DN', '')
|
||||
AUTH_LDAP_BIND_PASSWORD = _read_secret('auth_ldap_bind_password', environ.get('AUTH_LDAP_BIND_PASSWORD', ''))
|
||||
|
||||
# Set a string template that describes any user’s distinguished name based on the username.
|
||||
AUTH_LDAP_USER_DN_TEMPLATE = environ.get('AUTH_LDAP_USER_DN_TEMPLATE', None)
|
||||
|
||||
# Enable STARTTLS for ldap authentication.
|
||||
AUTH_LDAP_START_TLS = environ.get('AUTH_LDAP_START_TLS', 'False').lower() == 'true'
|
||||
|
||||
# Include this setting if you want to ignore certificate errors. This might be needed to accept a self-signed cert.
|
||||
# Note that this is a NetBox-specific setting which sets:
|
||||
# ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
|
||||
LDAP_IGNORE_CERT_ERRORS = environ.get('LDAP_IGNORE_CERT_ERRORS', 'False').lower() == 'true'
|
||||
|
||||
AUTH_LDAP_USER_SEARCH_BASEDN = environ.get('AUTH_LDAP_USER_SEARCH_BASEDN', '')
|
||||
AUTH_LDAP_USER_SEARCH_ATTR = environ.get('AUTH_LDAP_USER_SEARCH_ATTR', 'sAMAccountName')
|
||||
AUTH_LDAP_USER_SEARCH = LDAPSearch(
|
||||
AUTH_LDAP_USER_SEARCH_BASEDN,
|
||||
ldap.SCOPE_SUBTREE,
|
||||
"(" + AUTH_LDAP_USER_SEARCH_ATTR + "=%(user)s)"
|
||||
)
|
||||
|
||||
# This search ought to return all groups to which the user belongs. django_auth_ldap uses this to determine group
|
||||
# heirarchy.
|
||||
AUTH_LDAP_GROUP_SEARCH_BASEDN = environ.get('AUTH_LDAP_GROUP_SEARCH_BASEDN', '')
|
||||
AUTH_LDAP_GROUP_SEARCH_CLASS = environ.get('AUTH_LDAP_GROUP_SEARCH_CLASS', 'group')
|
||||
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(AUTH_LDAP_GROUP_SEARCH_BASEDN, ldap.SCOPE_SUBTREE,
|
||||
"(objectClass=" + AUTH_LDAP_GROUP_SEARCH_CLASS + ")")
|
||||
AUTH_LDAP_GROUP_TYPE = _import_group_type(environ.get('AUTH_LDAP_GROUP_TYPE', 'GroupOfNamesType'))
|
||||
|
||||
# Define a group required to login.
|
||||
AUTH_LDAP_REQUIRE_GROUP = environ.get('AUTH_LDAP_REQUIRE_GROUP_DN')
|
||||
|
||||
# Define special user types using groups. Exercise great caution when assigning superuser status.
|
||||
AUTH_LDAP_USER_FLAGS_BY_GROUP = {}
|
||||
|
||||
if AUTH_LDAP_REQUIRE_GROUP is not None:
|
||||
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
|
||||
"is_active": environ.get('AUTH_LDAP_REQUIRE_GROUP_DN', ''),
|
||||
"is_staff": environ.get('AUTH_LDAP_IS_ADMIN_DN', ''),
|
||||
"is_superuser": environ.get('AUTH_LDAP_IS_SUPERUSER_DN', '')
|
||||
}
|
||||
|
||||
# For more granular permissions, we can map LDAP groups to Django groups.
|
||||
AUTH_LDAP_FIND_GROUP_PERMS = environ.get('AUTH_LDAP_FIND_GROUP_PERMS', 'True').lower() == 'true'
|
||||
AUTH_LDAP_MIRROR_GROUPS = environ.get('AUTH_LDAP_MIRROR_GROUPS', '').lower() == 'true'
|
||||
|
||||
# Cache groups for one hour to reduce LDAP traffic
|
||||
AUTH_LDAP_CACHE_TIMEOUT = int(environ.get('AUTH_LDAP_CACHE_TIMEOUT', 3600))
|
||||
|
||||
# Populate the Django user from the LDAP directory.
|
||||
AUTH_LDAP_USER_ATTR_MAP = {
|
||||
"first_name": environ.get('AUTH_LDAP_ATTR_FIRSTNAME', 'givenName'),
|
||||
"last_name": environ.get('AUTH_LDAP_ATTR_LASTNAME', 'sn'),
|
||||
"email": environ.get('AUTH_LDAP_ATTR_MAIL', 'mail')
|
||||
}
|
||||
@@ -7,6 +7,10 @@ services:
|
||||
context: ..
|
||||
dockerfile: ci/Dockerfile-CI
|
||||
image: netbox:slm
|
||||
environment:
|
||||
- COVERAGE_FILE=/ci/.coverage
|
||||
volumes:
|
||||
- ./reports:/ci/reports
|
||||
netbox-worker:
|
||||
image: netbox:slm
|
||||
netbox-housekeeping:
|
||||
@@ -11,8 +11,6 @@ services:
|
||||
user: 'unit:root'
|
||||
volumes:
|
||||
- ./configuration:/etc/netbox/config:z,ro
|
||||
# - ./reports:/etc/netbox/reports:z,ro
|
||||
# - ./scripts:/etc/netbox/scripts:z,ro
|
||||
- netbox-media-files:/opt/netbox/netbox/media:z
|
||||
netbox-worker:
|
||||
<<: *netbox
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
coverage==7.2.2
|
||||
unittest-xml-reporting==3.2.0
|
||||
@@ -4,14 +4,15 @@ from extras.plugins import PluginConfig
|
||||
class SLMConfig(PluginConfig):
|
||||
name = 'netbox_slm'
|
||||
verbose_name = 'Software Lifecycle Management'
|
||||
description = 'Software Lifecycle Management'
|
||||
version = '1.2'
|
||||
author = 'Hedde van der Heide'
|
||||
author_email = 'hedde.vanderheide@ictu.nl'
|
||||
description = 'Software Lifecycle Management Netbox Plugin.'
|
||||
version = '1.3'
|
||||
author = 'ICTU'
|
||||
author_email = 'open-source-projects@ictu.nl'
|
||||
base_url = 'slm'
|
||||
required_settings = []
|
||||
default_settings = {
|
||||
'version_info': False
|
||||
}
|
||||
|
||||
|
||||
config = SLMConfig
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
from rest_framework import serializers
|
||||
|
||||
from netbox.api.serializers import NetBoxModelSerializer
|
||||
from netbox_slm.models import (
|
||||
SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation,
|
||||
)
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
|
||||
|
||||
class SoftwareProductSerializer(NetBoxModelSerializer):
|
||||
@@ -19,7 +17,7 @@ class SoftwareProductSerializer(NetBoxModelSerializer):
|
||||
]
|
||||
|
||||
def get_display(self, obj):
|
||||
return f"{obj.manufacturer.name} - {obj.name}"
|
||||
return f"{obj.manufacturer} - {obj}"
|
||||
|
||||
|
||||
class SoftwareProductVersionSerializer(NetBoxModelSerializer):
|
||||
@@ -35,7 +33,7 @@ class SoftwareProductVersionSerializer(NetBoxModelSerializer):
|
||||
]
|
||||
|
||||
def get_display(self, obj):
|
||||
return obj.name
|
||||
return f"{obj}"
|
||||
|
||||
|
||||
class SoftwareProductInstallationSerializer(NetBoxModelSerializer):
|
||||
@@ -52,4 +50,4 @@ class SoftwareProductInstallationSerializer(NetBoxModelSerializer):
|
||||
]
|
||||
|
||||
def get_display(self, obj):
|
||||
return obj
|
||||
return f"{obj}"
|
||||
|
||||
@@ -12,4 +12,4 @@ router.APIRootView = NetboxSLMRootView
|
||||
router.register("softwareproducts", SoftwareProductViewSet)
|
||||
router.register("softwareproductversions", SoftwareProductVersionViewSet)
|
||||
router.register("softwareproductinstallations", SoftwareProductInstallationViewSet)
|
||||
urlpatterns = router.urls
|
||||
urlpatterns = router.urls
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
from netbox.api.viewsets import NetBoxModelViewSet
|
||||
from rest_framework.routers import APIRootView
|
||||
|
||||
from netbox.api.viewsets import NetBoxModelViewSet
|
||||
from netbox_slm.api.serializers import (
|
||||
SoftwareProductSerializer, SoftwareProductVersionSerializer, SoftwareProductInstallationSerializer,
|
||||
)
|
||||
from netbox_slm.filtersets import (
|
||||
SoftwareProductFilterSet, SoftwareProductVersionFilterSet, SoftwareProductInstallationFilterSet,
|
||||
)
|
||||
from netbox_slm.models import (
|
||||
SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation,
|
||||
)
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
|
||||
|
||||
class NetboxSLMRootView(APIRootView):
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
from django.db.models import Q
|
||||
|
||||
from netbox.filtersets import NetBoxModelFilterSet
|
||||
from netbox_slm.models import *
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
|
||||
|
||||
class SoftwareProductFilterSet(NetBoxModelFilterSet):
|
||||
"""Filter capabilities for SoftwareProduct instances."""
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProduct
|
||||
fields = tuple()
|
||||
@@ -14,13 +15,13 @@ class SoftwareProductFilterSet(NetBoxModelFilterSet):
|
||||
"""Perform the filtered search."""
|
||||
if not value.strip():
|
||||
return queryset
|
||||
qs_filter = Q(name__icontains=value) | \
|
||||
Q(manufacturer__name__icontains=value)
|
||||
qs_filter = Q(name__icontains=value) | Q(manufacturer__name__icontains=value)
|
||||
return queryset.filter(qs_filter)
|
||||
|
||||
|
||||
class SoftwareProductVersionFilterSet(NetBoxModelFilterSet):
|
||||
"""Filter capabilities for SoftwareProductVersion instances."""
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProductVersion
|
||||
fields = (
|
||||
@@ -39,6 +40,7 @@ class SoftwareProductVersionFilterSet(NetBoxModelFilterSet):
|
||||
|
||||
class SoftwareProductInstallationFilterSet(NetBoxModelFilterSet):
|
||||
"""Filter capabilities for SoftwareProductInstallation instances."""
|
||||
|
||||
class Meta:
|
||||
model = SoftwareProductInstallation
|
||||
fields = tuple()
|
||||
|
||||
+2
-9
@@ -3,16 +3,9 @@ from django.urls import reverse_lazy
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from dcim.models import Manufacturer, Device
|
||||
from netbox.forms import (
|
||||
NetBoxModelForm,
|
||||
NetBoxModelCSVForm,
|
||||
NetBoxModelBulkEditForm,
|
||||
NetBoxModelFilterSetForm,
|
||||
)
|
||||
from netbox.forms import NetBoxModelForm, NetBoxModelCSVForm, NetBoxModelBulkEditForm, NetBoxModelFilterSetForm
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
from utilities.forms import (
|
||||
DynamicModelChoiceField, APISelect, TagFilterField, ChoiceField
|
||||
)
|
||||
from utilities.forms import DynamicModelChoiceField, APISelect, TagFilterField
|
||||
from virtualization.models import VirtualMachine
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ from utilities.querysets import RestrictedQuerySet
|
||||
class SoftwareProduct(NetBoxModel):
|
||||
name = models.CharField(max_length=128)
|
||||
description = models.CharField(max_length=255, null=True, blank=True)
|
||||
|
||||
|
||||
manufacturer = models.ForeignKey(
|
||||
to='dcim.Manufacturer',
|
||||
on_delete=models.PROTECT,
|
||||
@@ -89,4 +89,4 @@ class SoftwareProductInstallation(NetBoxModel):
|
||||
return self.device or self.virtualmachine
|
||||
|
||||
def render_type(self):
|
||||
return f"{'device' if self.device else 'virtualmachine'}"
|
||||
return 'device' if self.device else 'virtualmachine'
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from extras.plugins import PluginMenuButton, PluginMenuItem
|
||||
from utilities.choices import ButtonColorChoices
|
||||
|
||||
|
||||
menu_items = (
|
||||
PluginMenuItem(
|
||||
link='plugins:netbox_slm:softwareproduct_list',
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import django_tables2 as tables
|
||||
|
||||
from django.db.models import Count
|
||||
from django_tables2.utils import Accessor
|
||||
|
||||
from netbox.tables import NetBoxTable, ToggleColumn, columns
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
from netbox.tables import NetBoxTable, ChoiceFieldColumn, ToggleColumn, columns
|
||||
|
||||
|
||||
class SoftwareProductTable(NetBoxTable):
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
|
||||
|
||||
class ModelTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.p_name = "test product"
|
||||
self.v_name = "test version"
|
||||
|
||||
self.software_product = SoftwareProduct.objects.create(name=self.p_name)
|
||||
self.software_product_version = SoftwareProductVersion.objects.create(
|
||||
name=self.v_name, software_product=self.software_product
|
||||
)
|
||||
self.software_product_installation = SoftwareProductInstallation.objects.create(
|
||||
software_product=self.software_product, version=self.software_product_version
|
||||
)
|
||||
|
||||
def test_model_name(self):
|
||||
self.assertEqual(self.p_name, str(self.software_product))
|
||||
self.assertEqual(self.v_name, str(self.software_product_version))
|
||||
self.assertTrue(str(self.software_product_installation).isnumeric()) # should be PK
|
||||
|
||||
def test_absolute_url(self):
|
||||
self.assertEqual("/plugins/slm/software-products/1/", self.software_product.get_absolute_url())
|
||||
self.assertEqual("/plugins/slm/versions/1/", self.software_product_version.get_absolute_url())
|
||||
self.assertEqual("/plugins/slm/installations/1/", self.software_product_installation.get_absolute_url())
|
||||
|
||||
def test_get_installation_count(self):
|
||||
installation_ss = '<a href="/plugins/slm/installations/?q={}">1</a>'
|
||||
self.assertEqual(installation_ss.format(self.p_name), self.software_product.get_installation_count())
|
||||
self.assertEqual(installation_ss.format(self.v_name), self.software_product_version.get_installation_count())
|
||||
|
||||
def test_product_installation_methods(self):
|
||||
self.assertEqual("virtualmachine", self.software_product_installation.render_type())
|
||||
self.assertIsNone(self.software_product_installation.get_platform())
|
||||
@@ -1,16 +0,0 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
|
||||
|
||||
class ModelTestCase(TestCase):
|
||||
def test_smoke(self):
|
||||
software_product = SoftwareProduct.objects.create(name="test product")
|
||||
software_product_version = SoftwareProductVersion.objects.create(
|
||||
name="test version", software_product=software_product
|
||||
)
|
||||
software_product_installation = SoftwareProductInstallation.objects.create(
|
||||
software_product=software_product, version=software_product_version
|
||||
)
|
||||
|
||||
self.assertEqual('virtualmachine', software_product_installation.render_type())
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
from django.urls import path
|
||||
from netbox.views.generic import ObjectChangeLogView
|
||||
|
||||
from netbox.views.generic import ObjectChangeLogView
|
||||
from netbox_slm import views
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
|
||||
|
||||
+2
-6
@@ -1,10 +1,6 @@
|
||||
from netbox.views import generic
|
||||
from netbox_slm import filtersets
|
||||
from netbox_slm import forms
|
||||
from netbox_slm import tables
|
||||
from netbox_slm.models import (
|
||||
SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
)
|
||||
from netbox_slm import filtersets, forms, tables
|
||||
from netbox_slm.models import SoftwareProduct, SoftwareProductVersion, SoftwareProductInstallation
|
||||
|
||||
|
||||
class SoftwareProductListView(generic.ObjectListView):
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
[metadata]
|
||||
name = netbox-slm
|
||||
version = 1.2
|
||||
version = 1.3
|
||||
description = Software Lifecycle Management Netbox Plugin.
|
||||
# long_description = file: README.rst
|
||||
# long_description_content_type='text/x-rst'
|
||||
author = Hedde van der Heide
|
||||
author_email = hedde.vanderheide@ictu.nl
|
||||
author = ICTU
|
||||
author_email = open-source-projects@ictu.nl
|
||||
license = Apache 2.0
|
||||
classifiers =
|
||||
Environment :: Web Environment
|
||||
@@ -16,13 +14,13 @@ classifiers =
|
||||
Programming Language :: Python
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3 :: Only
|
||||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
Programming Language :: Python :: 3.10
|
||||
Programming Language :: Python :: 3.11
|
||||
Topic :: Internet :: WWW/HTTP
|
||||
Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
|
||||
[options]
|
||||
include_package_data = true
|
||||
packages = find:
|
||||
python_requires = >=3.7
|
||||
python_requires = >=3.9
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
from setuptools import setup, Extension
|
||||
from setuptools import setup
|
||||
|
||||
setup()
|
||||
setup()
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Project metadata
|
||||
sonar.organization=ictu
|
||||
sonar.projectKey=ICTU_netbox_slm
|
||||
sonar.projectName=netbox-slm
|
||||
sonar.projectVersion=1.3
|
||||
|
||||
# Path is relative to the sonar-project.properties file
|
||||
sonar.sources=netbox_slm
|
||||
sonar.python.version=3.9
|
||||
|
||||
# Unit tests
|
||||
sonar.python.xunit.reportPath=ci/reports/junit.xml
|
||||
sonar.python.coverage.reportPaths=ci/reports/coverage.xml
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
git clone -b release https://github.com/netbox-community/netbox-docker.git
|
||||
cd netbox-docker
|
||||
tee docker-compose.override.yml <<EOF
|
||||
version: '3.4'
|
||||
version: '3.7'
|
||||
services:
|
||||
netbox:
|
||||
ports:
|
||||
|
||||
Reference in New Issue
Block a user