Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/main_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ["3.12"]
netbox-version: ["v4.5.5"]
python-version: ["3.13"]
netbox-version: ["v4.5.10", "v4.6.2"]
services:
redis:
image: redis
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
max-parallel: 4
matrix:
python-version: ["3.13"]
netbox-version: ["v4.5.10", "v4.6.1"]
netbox-version: ["v4.5.10", "v4.6.2"]
services:
redis:
image: redis
Expand Down
2 changes: 1 addition & 1 deletion netbox_docker_plugin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class NetBoxDockerConfig(PluginConfig):
name = "netbox_docker_plugin"
verbose_name = " NetBox Docker Plugin"
description = "Manage Docker"
version = "5.2.0"
version = "5.3.0"
base_url = "docker"
min_version = "4.5.0"
author = "Vincent Simonin <vincent@saashup.com>, David Delassus <david.jose.delassus@gmail.com>"
Expand Down
5 changes: 5 additions & 0 deletions netbox_docker_plugin/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from utilities.query import dict_to_filter_params
from users.models import Token
from virtualization.api.serializers import VirtualMachineSerializer
from tenancy.api.serializers_.tenants import TenantSerializer, TenantGroupSerializer
from netbox.api.serializers import NetBoxModelSerializer, WritableNestedSerializer
from ..models.host import Host
from ..models.image import Image
Expand Down Expand Up @@ -240,6 +241,8 @@ class ImageSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name="plugins-api:netbox_docker_plugin-api:image-detail"
)
tenant_group = TenantGroupSerializer(nested=True, required=False, allow_null=True)
tenant = TenantSerializer(nested=True, required=False, allow_null=True)
host = NestedHostSerializer()
containers = NestedContainerSerializer(many=True, read_only=True)
registry = NestedRegistrySerializer()
Expand All @@ -252,6 +255,8 @@ class Meta:
"id",
"url",
"display",
"tenant_group",
"tenant",
"host",
"name",
"version",
Expand Down
11 changes: 11 additions & 0 deletions netbox_docker_plugin/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from django_filters import filters, ModelMultipleChoiceFilter
from django.db.models import Q
from tenancy.models import Tenant, TenantGroup
from netbox.filtersets import NetBoxModelFilterSet, BaseFilterSet
from .models.host import Host
from .models.image import Image
Expand Down Expand Up @@ -77,6 +78,16 @@ class ImageFilterSet(NetBoxModelFilterSet):
"""Image filterset definition class"""

name = filters.CharFilter(lookup_expr="icontains")
tenant_group_id = ModelMultipleChoiceFilter(
field_name="tenant_group_id",
queryset=TenantGroup.objects.all(),
label="Tenant Group (ID)",
)
tenant_id = ModelMultipleChoiceFilter(
field_name="tenant_id",
queryset=Tenant.objects.all(),
label="Tenant (ID)",
)
host_id = ModelMultipleChoiceFilter(
field_name="host_id",
queryset=Host.objects.all(),
Expand Down
40 changes: 39 additions & 1 deletion netbox_docker_plugin/forms/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
DynamicModelMultipleChoiceField,
DynamicModelChoiceField,
)
from tenancy.models import Tenant, TenantGroup
from netbox.forms import (
NetBoxModelForm,
NetBoxModelImportForm,
Expand All @@ -21,6 +22,13 @@
class ImageForm(NetBoxModelForm):
"""Image form definition class"""

tenant_group = DynamicModelChoiceField(
label="Tenant Group", queryset=TenantGroup.objects.all(), required=False
)
tenant = DynamicModelChoiceField(
label="Tenant", queryset=Tenant.objects.all(), required=False,
query_params={"group_id": "$tenant_group"},
)
host = DynamicModelChoiceField(
label="Host", queryset=Host.objects.all(), required=True
)
Expand All @@ -31,11 +39,18 @@ class ImageForm(NetBoxModelForm):
query_params={"host_id": "$host"},
)

fieldsets = (
FieldSet("host", "registry", "name", "version", "tags", name="General"),
FieldSet("tenant_group", "tenant", name="Tenancy"),
)

class Meta:
"""Image form definition Meta class"""

model = Image
fields = (
"tenant_group",
"tenant",
"host",
"registry",
"name",
Expand All @@ -44,6 +59,8 @@ class Meta:
)
labels = {
"name": "Name",
"tenant_group": "Tenant Group",
"tenant": "Tenant",
"host": "Host",
"registry": "Registry",
"version": "Version",
Expand All @@ -54,6 +71,16 @@ class ImageFilterForm(NetBoxModelFilterSetForm):
"""Image filter form definition class"""

model = Image
tenant_group_id = DynamicModelMultipleChoiceField(
queryset=TenantGroup.objects.all(),
required=False,
label="Tenant Group",
)
tenant_id = DynamicModelMultipleChoiceField(
queryset=Tenant.objects.all(),
required=False,
label="Tenant",
)
name = forms.CharField(label="Name", max_length=256, min_length=1, required=False)
version = forms.CharField(
label="Version", max_length=256, min_length=1, required=False
Expand Down Expand Up @@ -97,9 +124,20 @@ class Meta:
class ImageBulkEditForm(NetBoxModelBulkEditForm):
"""Image bulk edit form definition class"""

tenant_group = DynamicModelChoiceField(
queryset=TenantGroup.objects.all(),
required=False,
)
tenant = DynamicModelChoiceField(
queryset=Tenant.objects.all(),
required=False,
)
version = forms.CharField(
required=False,
)

model = Image
fieldsets = (FieldSet("version", name="General"),)
fieldsets = (
FieldSet("version", name="General"),
FieldSet("tenant_group", "tenant", name="Tenancy"),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# pylint: disable=C0103
"""Migration file"""

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):
"""Migration file"""

dependencies = [
("netbox_docker_plugin", "1044_host_virtual_machine"),
]

operations = [
migrations.AddField(
model_name="image",
name="tenant",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="images",
to="tenancy.tenant",
),
),
migrations.AddField(
model_name="image",
name="tenant_group",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="images",
to="tenancy.tenantgroup",
),
),
]
15 changes: 15 additions & 0 deletions netbox_docker_plugin/models/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
MinValueValidator,
MaxValueValidator,
)
from tenancy.models import Tenant, TenantGroup
from netbox.models import NetBoxModel
from .host import Host
from .registry import Registry
Expand All @@ -16,6 +17,20 @@
class Image(NetBoxModel):
"""Image definition class"""

tenant_group = models.ForeignKey(
TenantGroup,
on_delete=models.SET_NULL,
related_name="images",
blank=True,
null=True,
)
tenant = models.ForeignKey(
Tenant,
on_delete=models.SET_NULL,
related_name="images",
blank=True,
null=True,
)
host = models.ForeignKey(Host, on_delete=models.CASCADE, related_name="images")
registry = models.ForeignKey(
Registry,
Expand Down
6 changes: 6 additions & 0 deletions netbox_docker_plugin/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ class Meta(NetBoxTable.Meta):
class ImageTable(NetBoxTable):
"""Image Table definition class"""

tenant_group = tables.Column(linkify=True)
tenant = tables.Column(linkify=True)
host = tables.Column(linkify=True)
registry = tables.Column(linkify=True)
name = tables.Column(linkify=True)
Expand All @@ -162,6 +164,8 @@ class Meta(NetBoxTable.Meta):
fields = (
"pk",
"id",
"tenant_group",
"tenant",
"host",
"name",
"version",
Expand All @@ -172,6 +176,8 @@ class Meta(NetBoxTable.Meta):
"tags",
)
default_columns = (
"tenant_group",
"tenant",
"host",
"name",
"version",
Expand Down
25 changes: 25 additions & 0 deletions netbox_docker_plugin/templates/netbox_docker_plugin/image.html
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,31 @@ <h2 class="card-header">Image</h2>
</tr>
</table>
</div>
<div class="card">
<h2 class="card-header">Tenancy</h2>
<table class="table table-hover attr-table">
<tr>
<th scope="row">Tenant Group</th>
<td>
{% if object.tenant_group %}
<a href="{{ object.tenant_group.get_absolute_url }}">{{ object.tenant_group }}</a>
{% else %}
{{ None|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">Tenant</th>
<td>
{% if object.tenant %}
<a href="{{ object.tenant.get_absolute_url }}">{{ object.tenant }}</a>
{% else %}
{{ None|placeholder }}
{% endif %}
</td>
</tr>
</table>
</div>
{% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %}
{% plugin_left_page object %}
Expand Down
14 changes: 13 additions & 1 deletion netbox_docker_plugin/tests/image/test_image_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.urls import reverse
from core.models import ObjectType
from rest_framework import status
from tenancy.models import Tenant, TenantGroup
from users.models import ObjectPermission
from utilities.testing import APIViewTestCases
from netbox_docker_plugin.models.host import Host
Expand Down Expand Up @@ -41,8 +42,17 @@ def setUpTestData(cls) -> None:

registry = Registry.objects.filter(name="dockerhub")[0]

tenant_group = TenantGroup(name="Group 1", slug="group-1")
tenant_group.save()
tenant = Tenant.objects.create(
name="Tenant 1", slug="tenant-1", group=tenant_group
)

Image.objects.create(host=host1, name="image1", registry=registry)
Image.objects.create(host=host1, name="image2", registry=registry)
Image.objects.create(
host=host1, name="image2", registry=registry,
tenant=tenant, tenant_group=tenant_group,
)
Image.objects.create(
host=host2,
name="image3",
Expand All @@ -60,6 +70,8 @@ def setUpTestData(cls) -> None:
"host": host1.pk,
"name": "image5",
"registry": registry.pk,
"tenant": tenant.pk,
"tenant_group": tenant_group.pk,
},
{
"host": host2.pk,
Expand Down
Loading
Loading