diff --git a/.github/workflows/pr_ci.yml b/.github/workflows/pr_ci.yml index 46cb954..e81880c 100644 --- a/.github/workflows/pr_ci.yml +++ b/.github/workflows/pr_ci.yml @@ -14,8 +14,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.1"] services: redis: image: redis diff --git a/netbox_docker_plugin/__init__.py b/netbox_docker_plugin/__init__.py index e2acf58..49c8c57 100644 --- a/netbox_docker_plugin/__init__.py +++ b/netbox_docker_plugin/__init__.py @@ -11,7 +11,7 @@ class NetBoxDockerConfig(PluginConfig): name = "netbox_docker_plugin" verbose_name = " NetBox Docker Plugin" description = "Manage Docker" - version = "5.0.1" + version = "5.1.0" base_url = "docker" min_version = "4.5.0" author = "Vincent Simonin , David Delassus " diff --git a/netbox_docker_plugin/api/serializers.py b/netbox_docker_plugin/api/serializers.py index 7dfa0db..2c310df 100644 --- a/netbox_docker_plugin/api/serializers.py +++ b/netbox_docker_plugin/api/serializers.py @@ -175,7 +175,11 @@ class Meta: "operation", "hostname", "cap_add", + "cap_drop", "log_driver", + "secOpt", + "pid_mode", + "extra_hosts", "cmd", ) @@ -481,6 +485,10 @@ class Meta: "hostname", "restart_policy", "cap_add", + "cap_drop", + "secOpt", + "pid_mode", + "extra_hosts", "cmd", "ports", "env", diff --git a/netbox_docker_plugin/forms/container.py b/netbox_docker_plugin/forms/container.py index 3ff3909..d0c5362 100644 --- a/netbox_docker_plugin/forms/container.py +++ b/netbox_docker_plugin/forms/container.py @@ -19,6 +19,7 @@ Container, ContainerRestartPolicyChoices, ContainerCapAddChoices, + ContainerCapDropChoices, ) from ..models.image import Image @@ -36,6 +37,9 @@ class ContainerForm(NetBoxModelForm): query_params={"host_id": "$host"}, ) cap_add = forms.MultipleChoiceField(choices=ContainerCapAddChoices, required=False) + cap_drop = forms.MultipleChoiceField( + choices=ContainerCapDropChoices, required=False + ) class Meta: """Container form definition Meta class""" @@ -48,6 +52,10 @@ class Meta: "hostname", "restart_policy", "cap_add", + "cap_drop", + "secOpt", + "pid_mode", + "extra_hosts", "log_driver", "cmd", "tags", @@ -59,6 +67,10 @@ class Meta: "hostname": "Hostname", "restart_policy": "Restart Policy", "cap_add": "Add Host capabilities", + "cap_drop": "Drop Host capabilities", + "secOpt": "Security options (separate by comma)", + "pid_mode": "PID mode", + "extra_hosts": "Extra hosts (separate by comma). Specified in the form hostname:IP", "log_driver": "Logging driver", "cmd": "Command", } @@ -73,6 +85,9 @@ class ContainerEditForm(NetBoxModelForm): required=True, ) cap_add = forms.MultipleChoiceField(choices=ContainerCapAddChoices, required=False) + cap_drop = forms.MultipleChoiceField( + choices=ContainerCapDropChoices, required=False + ) class Meta: """Container form definition Meta class""" @@ -84,6 +99,10 @@ class Meta: "hostname", "restart_policy", "cap_add", + "cap_drop", + "secOpt", + "pid_mode", + "extra_hosts", "log_driver", "cmd", "tags", @@ -94,6 +113,10 @@ class Meta: "hostname": "Hostname", "restart_policy": "Restart Policy", "cap_add": "Add Host capabilities", + "cap_drop": "Drop Host capabilities", + "secOpt": "Security options (separate by comma)", + "pid_mode": "PID mode", + "extra_hosts": "Extra hosts (separate by comma). Specified in the form hostname:IP", "log_driver": "Logging driver", "cmd": "Command", } diff --git a/netbox_docker_plugin/migrations/1043_container_cap_drop_container_extra_hosts_and_more.py b/netbox_docker_plugin/migrations/1043_container_cap_drop_container_extra_hosts_and_more.py new file mode 100644 index 0000000..9fd5af3 --- /dev/null +++ b/netbox_docker_plugin/migrations/1043_container_cap_drop_container_extra_hosts_and_more.py @@ -0,0 +1,60 @@ +# pylint: disable=C0103 +"""Migration file""" + +import django.contrib.postgres.fields +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + """Migration file""" + + dependencies = [ + ("netbox_docker_plugin", "1042_registry_username_max_length"), + ] + + operations = [ + migrations.AddField( + model_name="container", + name="cap_drop", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.CharField(blank=True, max_length=32, null=True), + blank=True, + null=True, + ), + ), + migrations.AddField( + model_name="container", + name="extra_hosts", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.CharField(blank=True, max_length=512, null=True), + blank=True, + null=True, + ), + ), + migrations.AddField( + model_name="container", + name="pid_mode", + field=models.CharField(blank=True, max_length=512, null=True), + ), + migrations.AddField( + model_name="container", + name="secOpt", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.CharField(blank=True, max_length=512, null=True), + blank=True, + null=True, + ), + ), + migrations.AlterField( + model_name="image", + name="size", + field=models.IntegerField( + default=0, + validators=[ + django.core.validators.MinValueValidator(limit_value=0), + django.core.validators.MaxValueValidator(limit_value=8192), + ], + ), + ), + ] diff --git a/netbox_docker_plugin/models/container.py b/netbox_docker_plugin/models/container.py index 761fd68..870e319 100644 --- a/netbox_docker_plugin/models/container.py +++ b/netbox_docker_plugin/models/container.py @@ -110,6 +110,41 @@ class ContainerCapAddChoices(ChoiceSet): ("SYS_PTRACE", "SYS_PTRACE"), ("SYS_RESOURCE", "SYS_RESOURCE"), ("SYS_NICE", "SYS_NICE"), + ("ALL", "ALL"), + ] + + +class ContainerCapDropChoices(ChoiceSet): + """cap-drop choices definition class""" + + key = "Container.cap_drop" + + CHOICES = [ + ("AUDIT_WRITE", "AUDIT_WRITE"), + ("CHOWN", "CHOWN"), + ("DAC_OVERRIDE", "DAC_OVERRIDE"), + ("FOWNER", "FOWNER"), + ("FSETID", "FSETID"), + ("KILL", "KILL"), + ("MKNOD", "MKNOD"), + ("NET_BIND_SERVICE", "NET_BIND_SERVICE"), + ("NET_RAW", "NET_RAW"), + ("SETFCAP", "SETFCAP"), + ("SETGID", "SETGID"), + ("SETPCAP", "SETPCAP"), + ("SETUID", "SETUID"), + ("SYS_CHROOT", "SYS_CHROOT"), + ("ALL", "ALL"), + ] + + +class PidModeChoices(ChoiceSet): + """Pid mode choices definition class""" + + key = "Container.pid_mode" + + CHOICES = [ + ("host", "host"), ] @@ -170,11 +205,34 @@ class Container(NetBoxModel): null=True, blank=True, ) + cap_drop = ArrayField( + models.CharField( + max_length=32, blank=True, null=True, choices=ContainerCapDropChoices + ), + null=True, + blank=True, + ) log_driver = models.CharField( max_length=32, null=True, blank=True, ) + secOpt = ArrayField( + models.CharField(max_length=512, blank=True, null=True), + null=True, + blank=True, + ) + pid_mode = models.CharField( + max_length=512, + choices=PidModeChoices, + null=True, + blank=True, + ) + extra_hosts = ArrayField( + models.CharField(max_length=512, blank=True, null=True), + null=True, + blank=True, + ) cmd = ArrayField( models.CharField(max_length=1024, blank=True, null=True), null=True, diff --git a/netbox_docker_plugin/models/image.py b/netbox_docker_plugin/models/image.py index 2d63e49..5a3a050 100644 --- a/netbox_docker_plugin/models/image.py +++ b/netbox_docker_plugin/models/image.py @@ -41,7 +41,7 @@ class Image(NetBoxModel): default=0, validators=[ MinValueValidator(limit_value=0), - MaxValueValidator(limit_value=4096), + MaxValueValidator(limit_value=8192), ], ) ImageID = models.CharField( diff --git a/netbox_docker_plugin/tables.py b/netbox_docker_plugin/tables.py index 509a99f..ea1a419 100644 --- a/netbox_docker_plugin/tables.py +++ b/netbox_docker_plugin/tables.py @@ -385,6 +385,10 @@ class Meta(NetBoxTable.Meta): "hostname", "restart_policy", "cap_add", + "cap_drop", + "secOpt", + "pid_mode", + "extra_hosts", "cmd", "port_count", "mount_count", diff --git a/netbox_docker_plugin/templates/netbox_docker_plugin/container.html b/netbox_docker_plugin/templates/netbox_docker_plugin/container.html index 4219066..8f02743 100644 --- a/netbox_docker_plugin/templates/netbox_docker_plugin/container.html +++ b/netbox_docker_plugin/templates/netbox_docker_plugin/container.html @@ -40,6 +40,22 @@

Container

Host Capacities added {{ object.cap_add }} + + Host Capacities dropped + {{ object.cap_drop }} + + + Security options + {{ object.secOpt }} + + + PID mode + {{ object.pid_mode|placeholder }} + + + Extra hosts added + {{ object.extra_hosts }} + Status {{ object.status|placeholder }} diff --git a/netbox_docker_plugin/tests/container/test_container_api.py b/netbox_docker_plugin/tests/container/test_container_api.py index 6e6d1f4..f8d7112 100644 --- a/netbox_docker_plugin/tests/container/test_container_api.py +++ b/netbox_docker_plugin/tests/container/test_container_api.py @@ -30,14 +30,18 @@ class ContainerApiTestCase( brief_fields = [ "ContainerID", "cap_add", + "cap_drop", "cmd", "display", + "extra_hosts", "hostname", "id", "log_driver", "name", "operation", + "pid_mode", "restart_policy", + "secOpt", "state", "status", "url", @@ -195,6 +199,20 @@ def setUpTestData(cls) -> None: "cap_add": ["NET_ADMIN"], "cmd": ["cat", "/etc/hosts"], }, + { + "host": host2.pk, + "image": image2.pk, + "name": "container11", + "ports": [], + "env": [], + "labels": [], + "sysctls": [], + "cap_add": [], + "cap_drop": ["FSETID", "MKNOD"], + "pid_mode": "host", + "extra_hosts": ["test1:192.168.1.2", "test2:192.168.1.3"], + "secOpt": ["apparmor:unconfined"], + }, ] def test_that_patch_overwrites_data_only_when_explicitly_set(self): diff --git a/netbox_docker_plugin/tests/container/test_container_views.py b/netbox_docker_plugin/tests/container/test_container_views.py index 361671e..2527a00 100644 --- a/netbox_docker_plugin/tests/container/test_container_views.py +++ b/netbox_docker_plugin/tests/container/test_container_views.py @@ -67,8 +67,12 @@ def setUpTestData(cls): "image": image1.pk, "restart_policy": "unless-stopped", "cap_add": ["NET_ADMIN"], + "cap_drop": ["FSETID", "MKNOD"], + "pid_mode": "host", + "extra_hosts": "test1:192.168.1.2,test2:192.168.1.3", + "secOpt": "apparmor:unconfined", "log_driver": "syslog", - "cmd": "ls,-al" + "cmd": "ls,-al", } cls.csv_data = ( diff --git a/pyproject.toml b/pyproject.toml index 3efd449..9b50a24 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "netbox-docker-plugin" -version = "5.0.1" +version = "5.1.0" authors = [ { name="Vincent Simonin", email="vincent@saashup.com" }, { name="David Delassus", email="david.jose.delassus@gmail.com" }