netbox-docker-plugin 1.3.0__tar.gz → 1.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. {netbox-docker-plugin-1.3.0/netbox_docker_plugin.egg-info → netbox-docker-plugin-1.4.0}/PKG-INFO +1 -1
  2. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/__init__.py +1 -1
  3. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/api/serializers.py +41 -2
  4. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/api/views.py +9 -1
  5. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/filtersets.py +25 -1
  6. netbox-docker-plugin-1.4.0/netbox_docker_plugin/forms/bind.py +46 -0
  7. netbox-docker-plugin-1.4.0/netbox_docker_plugin/migrations/0022_bind_bind_netbox_docker_plugin_bind_unique_bind.py +74 -0
  8. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/models/container.py +38 -0
  9. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tables.py +31 -1
  10. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/templates/netbox_docker_plugin/container.html +14 -0
  11. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/container/test_container_api.py +4 -0
  12. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/urls.py +22 -0
  13. netbox-docker-plugin-1.4.0/netbox_docker_plugin/views/bind.py +28 -0
  14. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/views/container.py +18 -2
  15. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0/netbox_docker_plugin.egg-info}/PKG-INFO +1 -1
  16. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin.egg-info/SOURCES.txt +3 -0
  17. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/pyproject.toml +1 -1
  18. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/LICENSE +0 -0
  19. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/MANIFEST.in +0 -0
  20. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/README.md +0 -0
  21. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/api/__init__.py +0 -0
  22. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/api/urls.py +0 -0
  23. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/forms/__init__.py +0 -0
  24. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/forms/container.py +0 -0
  25. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/forms/env.py +0 -0
  26. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/forms/host.py +0 -0
  27. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/forms/image.py +0 -0
  28. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/forms/label.py +0 -0
  29. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/forms/mount.py +0 -0
  30. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/forms/network.py +0 -0
  31. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/forms/network_setting.py +0 -0
  32. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/forms/port.py +0 -0
  33. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/forms/registry.py +0 -0
  34. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/forms/volume.py +0 -0
  35. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0001_initial.py +0 -0
  36. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0002_image.py +0 -0
  37. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0003_image_size.py +0 -0
  38. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0004_volume.py +0 -0
  39. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0005_network.py +0 -0
  40. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0006_container_port_mount_label_env_and_more.py +0 -0
  41. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0007_remove_container_netbox_docker_plugin_container_unique_name_host__and_more.py +0 -0
  42. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0008_alter_network_unique_together_network_networkid_and_more.py +0 -0
  43. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0009_remove_container_network_networksettings_and_more.py +0 -0
  44. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0010_container_containerid_and_more.py +0 -0
  45. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0011_host_token.py +0 -0
  46. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0012_host_state.py +0 -0
  47. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0013_host_netbox_url.py +0 -0
  48. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0014_container_operation.py +0 -0
  49. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0015_remove_mount_netbox_docker_plugin_mount_unique_volume_and_more.py +0 -0
  50. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0016_alter_env_value.py +0 -0
  51. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0017_network_state.py +0 -0
  52. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0018_alter_mount_volume_alter_networksetting_network.py +0 -0
  53. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0019_host_agent_version_host_docker_api_version.py +0 -0
  54. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0020_container_hostname.py +0 -0
  55. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/0021_registry_and_more.py +0 -0
  56. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/migrations/__init__.py +0 -0
  57. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/models/__init__.py +0 -0
  58. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/models/host.py +0 -0
  59. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/models/image.py +0 -0
  60. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/models/network.py +0 -0
  61. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/models/registry.py +0 -0
  62. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/models/volume.py +0 -0
  63. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/navigation.py +0 -0
  64. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/templates/netbox_docker_plugin/host.html +0 -0
  65. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/templates/netbox_docker_plugin/image.html +0 -0
  66. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/templates/netbox_docker_plugin/network.html +0 -0
  67. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/templates/netbox_docker_plugin/registry.html +0 -0
  68. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/templates/netbox_docker_plugin/volume.html +0 -0
  69. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/templatetags/__init__.py +0 -0
  70. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/templatetags/host.py +0 -0
  71. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/__init__.py +0 -0
  72. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/base.py +0 -0
  73. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/container/__init__.py +0 -0
  74. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/container/test_container_operation_view.py +0 -0
  75. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/container/test_container_validation.py +0 -0
  76. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/container/test_container_views.py +0 -0
  77. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/host/__init__.py +0 -0
  78. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/host/test_host_api.py +0 -0
  79. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/host/test_host_views.py +0 -0
  80. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/host/test_replace_password.py +0 -0
  81. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/image/__init__.py +0 -0
  82. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/image/test_image_api.py +0 -0
  83. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/image/test_image_views.py +0 -0
  84. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/network/__init__.py +0 -0
  85. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/network/test_network_api.py +0 -0
  86. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/network/test_network_views.py +0 -0
  87. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/registry/__init__.py +0 -0
  88. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/registry/test_registry_api.py +0 -0
  89. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/registry/test_registry_views.py +0 -0
  90. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/test_init.py +0 -0
  91. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/volume/__init__.py +0 -0
  92. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/volume/test_volume_api.py +0 -0
  93. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/tests/volume/test_volume_views.py +0 -0
  94. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/utilities/__init__.py +0 -0
  95. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/views/__init__.py +0 -0
  96. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/views/env.py +0 -0
  97. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/views/host.py +0 -0
  98. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/views/image.py +0 -0
  99. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/views/label.py +0 -0
  100. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/views/mount.py +0 -0
  101. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/views/network.py +0 -0
  102. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/views/network_setting.py +0 -0
  103. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/views/port.py +0 -0
  104. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/views/registry.py +0 -0
  105. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin/views/volume.py +0 -0
  106. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin.egg-info/dependency_links.txt +0 -0
  107. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/netbox_docker_plugin.egg-info/top_level.txt +0 -0
  108. {netbox-docker-plugin-1.3.0 → netbox-docker-plugin-1.4.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: netbox-docker-plugin
3
- Version: 1.3.0
3
+ Version: 1.4.0
4
4
  Summary: Manage Docker with Netbox & style.
5
5
  Author-email: Vincent Simonin <vincent@saashup.com>
6
6
  Project-URL: Homepage, https://github.com/SaaShup/netbox-docker-plugin
@@ -10,7 +10,7 @@ class NetBoxDockerConfig(PluginConfig):
10
10
  name = "netbox_docker_plugin"
11
11
  verbose_name = " NetBox Docker Plugin"
12
12
  description = "Manage Docker"
13
- version = "1.3.0"
13
+ version = "1.4.0"
14
14
  base_url = "docker"
15
15
  author= "Vincent Simonin"
16
16
  author_email= "vincent@saashup.com"
@@ -9,7 +9,15 @@ from ..models.host import Host
9
9
  from ..models.image import Image
10
10
  from ..models.volume import Volume
11
11
  from ..models.network import Network
12
- from ..models.container import Container, Port, Env, Label, Mount, NetworkSetting
12
+ from ..models.container import (
13
+ Container,
14
+ Port,
15
+ Env,
16
+ Label,
17
+ Mount,
18
+ Bind,
19
+ NetworkSetting,
20
+ )
13
21
  from ..models.registry import Registry
14
22
 
15
23
 
@@ -179,7 +187,7 @@ class ImageSerializer(NetBoxModelSerializer):
179
187
  )
180
188
  host = NestedHostSerializer()
181
189
  containers = NestedContainerSerializer(many=True, read_only=True)
182
- registry = NestedRegistrySerializer(read_only=True)
190
+ registry = NestedRegistrySerializer()
183
191
 
184
192
  class Meta:
185
193
  """Image Serializer Meta class"""
@@ -316,6 +324,19 @@ class MountSerializer(serializers.ModelSerializer):
316
324
  )
317
325
 
318
326
 
327
+ class BindSerializer(serializers.ModelSerializer):
328
+ """Container Bind Serializer class"""
329
+
330
+ class Meta:
331
+ """Container Bind Serializer Meta class"""
332
+
333
+ model = Bind
334
+ fields = (
335
+ "host_path",
336
+ "container_path",
337
+ )
338
+
339
+
319
340
  class NetworkSettingSerializer(serializers.ModelSerializer):
320
341
  """Container NetworkSetting Serializer class"""
321
342
 
@@ -340,6 +361,7 @@ class ContainerSerializer(NetBoxModelSerializer):
340
361
  env = EnvSerializer(many=True, required=False)
341
362
  labels = LabelSerializer(many=True, required=False)
342
363
  mounts = MountSerializer(many=True, required=False)
364
+ binds = BindSerializer(many=True, required=False)
343
365
  network_settings = NetworkSettingSerializer(many=True, required=False)
344
366
 
345
367
  class Meta:
@@ -361,6 +383,7 @@ class ContainerSerializer(NetBoxModelSerializer):
361
383
  "env",
362
384
  "labels",
363
385
  "mounts",
386
+ "binds",
364
387
  "network_settings",
365
388
  "custom_fields",
366
389
  "created",
@@ -374,6 +397,7 @@ class ContainerSerializer(NetBoxModelSerializer):
374
397
  attrs.pop("env", None)
375
398
  attrs.pop("labels", None)
376
399
  attrs.pop("mounts", None)
400
+ attrs.pop("binds", None)
377
401
  attrs.pop("network_settings", None)
378
402
 
379
403
  super().validate(attrs)
@@ -385,6 +409,7 @@ class ContainerSerializer(NetBoxModelSerializer):
385
409
  env_data = validated_data.pop("env", None)
386
410
  labels_data = validated_data.pop("labels", None)
387
411
  mounts_data = validated_data.pop("mounts", None)
412
+ binds_data = validated_data.pop("binds", None)
388
413
  network_settings_data = validated_data.pop("network_settings", None)
389
414
 
390
415
  container = super().create(validated_data)
@@ -407,6 +432,12 @@ class ContainerSerializer(NetBoxModelSerializer):
407
432
  obj.full_clean()
408
433
  obj.save()
409
434
 
435
+ if binds_data is not None:
436
+ for bind in binds_data:
437
+ obj = Bind(container=container, **bind)
438
+ obj.full_clean()
439
+ obj.save()
440
+
410
441
  if network_settings_data is not None:
411
442
  for network_setting in network_settings_data:
412
443
  obj = NetworkSetting(container=container, **network_setting)
@@ -420,6 +451,7 @@ class ContainerSerializer(NetBoxModelSerializer):
420
451
  env_data = validated_data.pop("env", None)
421
452
  labels_data = validated_data.pop("labels", None)
422
453
  mounts_data = validated_data.pop("mounts", None)
454
+ binds_data = validated_data.pop("binds", None)
423
455
  network_settings_data = validated_data.pop("network_settings", None)
424
456
 
425
457
  container = super().update(instance, validated_data)
@@ -446,6 +478,13 @@ class ContainerSerializer(NetBoxModelSerializer):
446
478
  obj.full_clean()
447
479
  obj.save()
448
480
 
481
+ Bind.objects.filter(container=container).delete()
482
+ if binds_data is not None:
483
+ for bind in binds_data:
484
+ obj = Bind(container=container, **bind)
485
+ obj.full_clean()
486
+ obj.save()
487
+
449
488
  NetworkSetting.objects.filter(container=container).delete()
450
489
  if network_settings_data is not None:
451
490
  for network_setting in network_settings_data:
@@ -79,7 +79,15 @@ class ContainerViewSet(NetBoxModelViewSet):
79
79
  """Container view set class"""
80
80
 
81
81
  queryset = Container.objects.prefetch_related(
82
- "network_settings", "mounts", "env", "image", "host", "ports", "labels", "tags"
82
+ "network_settings",
83
+ "mounts",
84
+ "binds",
85
+ "env",
86
+ "image",
87
+ "host",
88
+ "ports",
89
+ "labels",
90
+ "tags",
83
91
  )
84
92
  filterset_class = filtersets.ContainerFilterSet
85
93
  serializer_class = ContainerSerializer
@@ -7,7 +7,15 @@ from .models.host import Host
7
7
  from .models.image import Image
8
8
  from .models.volume import Volume
9
9
  from .models.network import Network
10
- from .models.container import Container, Env, Label, Port, Mount, NetworkSetting
10
+ from .models.container import (
11
+ Container,
12
+ Env,
13
+ Label,
14
+ Port,
15
+ Mount,
16
+ Bind,
17
+ NetworkSetting,
18
+ )
11
19
  from .models.registry import Registry
12
20
 
13
21
 
@@ -240,6 +248,22 @@ class MountFilterSet(BaseFilterSet):
240
248
  fields = ("id",)
241
249
 
242
250
 
251
+ class BindFilterSet(BaseFilterSet):
252
+ """Bind filterset definition class"""
253
+
254
+ container_id = ModelMultipleChoiceFilter(
255
+ field_name="container_id",
256
+ queryset=Container.objects.all(),
257
+ label="Container (ID)",
258
+ )
259
+
260
+ class Meta:
261
+ """Bind filterset definition meta class"""
262
+
263
+ model = Bind
264
+ fields = ("id",)
265
+
266
+
243
267
  class NetworkSettingFilterSet(BaseFilterSet):
244
268
  """NetworkSetting filterset definition class"""
245
269
 
@@ -0,0 +1,46 @@
1
+ """Mount Form definition"""
2
+
3
+ from django import forms
4
+ from utilities.forms.mixins import BootstrapMixin
5
+ from utilities.forms.fields import (
6
+ DynamicModelMultipleChoiceField,
7
+ DynamicModelChoiceField,
8
+ )
9
+ from netbox.forms import (
10
+ NetBoxModelFilterSetForm,
11
+ )
12
+ from ..models.container import Bind, Container
13
+
14
+
15
+ class BindForm(BootstrapMixin, forms.ModelForm):
16
+ """Bind form definition class"""
17
+
18
+ container = DynamicModelChoiceField(
19
+ label="Container", queryset=Container.objects.all(), required=True
20
+ )
21
+
22
+ class Meta:
23
+ """Mount form definition Meta class"""
24
+
25
+ model = Bind
26
+ fields = (
27
+ "container",
28
+ "host_path",
29
+ "container_path",
30
+ )
31
+ labels = {
32
+ "container": "Container",
33
+ "host_path": "Path to mount on host",
34
+ "container_path": "Mountpoint in container",
35
+ }
36
+
37
+
38
+ class BindFilterForm(NetBoxModelFilterSetForm):
39
+ """Bind filter form definition class"""
40
+
41
+ model = Bind
42
+ container_id = DynamicModelMultipleChoiceField(
43
+ queryset=Container.objects.all(),
44
+ required=False,
45
+ label="Container",
46
+ )
@@ -0,0 +1,74 @@
1
+ # pylint: disable=C0103
2
+ """ Migration file """
3
+
4
+ import django.core.validators
5
+ import django.db.models.deletion
6
+ from django.db import migrations, models
7
+
8
+
9
+ class Migration(migrations.Migration):
10
+ """ Migration file """
11
+
12
+ dependencies = [
13
+ ("netbox_docker_plugin", "0021_registry_and_more"),
14
+ ]
15
+
16
+ operations = [
17
+ migrations.CreateModel(
18
+ name="Bind",
19
+ fields=[
20
+ (
21
+ "id",
22
+ models.BigAutoField(
23
+ auto_created=True, primary_key=True, serialize=False
24
+ ),
25
+ ),
26
+ (
27
+ "host_path",
28
+ models.CharField(
29
+ max_length=1024,
30
+ validators=[
31
+ django.core.validators.MinLengthValidator(
32
+ limit_value=1,
33
+ ),
34
+ django.core.validators.MaxLengthValidator(
35
+ limit_value=1024,
36
+ ),
37
+ ],
38
+ ),
39
+ ),
40
+ (
41
+ "container_path",
42
+ models.CharField(
43
+ max_length=1024,
44
+ validators=[
45
+ django.core.validators.MinLengthValidator(
46
+ limit_value=1,
47
+ ),
48
+ django.core.validators.MaxLengthValidator(
49
+ limit_value=1024,
50
+ ),
51
+ ],
52
+ ),
53
+ ),
54
+ (
55
+ "container",
56
+ models.ForeignKey(
57
+ on_delete=django.db.models.deletion.CASCADE,
58
+ related_name="binds",
59
+ to="netbox_docker_plugin.container",
60
+ ),
61
+ ),
62
+ ],
63
+ options={
64
+ "ordering": ("container", "container_path", "host_path"),
65
+ },
66
+ ),
67
+ migrations.AddConstraint(
68
+ model_name="bind",
69
+ constraint=models.UniqueConstraint(
70
+ fields=("container", "container_path", "host_path"),
71
+ name="netbox_docker_plugin_bind_unique_bind",
72
+ ),
73
+ ),
74
+ ]
@@ -307,6 +307,44 @@ class Mount(models.Model):
307
307
  )
308
308
 
309
309
 
310
+ class Bind(models.Model):
311
+ """Bind definition class"""
312
+
313
+ objects = RestrictedQuerySet.as_manager()
314
+
315
+ container = models.ForeignKey(
316
+ Container, on_delete=models.CASCADE, related_name="binds"
317
+ )
318
+ host_path = models.CharField(
319
+ max_length=1024,
320
+ validators=[
321
+ MinLengthValidator(limit_value=1),
322
+ MaxLengthValidator(limit_value=1024),
323
+ ],
324
+ )
325
+ container_path = models.CharField(
326
+ max_length=1024,
327
+ validators=[
328
+ MinLengthValidator(limit_value=1),
329
+ MaxLengthValidator(limit_value=1024),
330
+ ],
331
+ )
332
+
333
+ class Meta:
334
+ """Mount Model Meta Class"""
335
+
336
+ ordering = ("container", "container_path", "host_path")
337
+ constraints = (
338
+ models.UniqueConstraint(
339
+ fields=["container", "container_path", "host_path"],
340
+ name="%(app_label)s_%(class)s_unique_bind",
341
+ ),
342
+ )
343
+
344
+ def __str__(self):
345
+ return f"{self.host_path}:{self.container_path}"
346
+
347
+
310
348
  class NetworkSetting(models.Model):
311
349
  """NetworkSetting definition class"""
312
350
 
@@ -6,7 +6,15 @@ from .models.host import Host
6
6
  from .models.image import Image
7
7
  from .models.volume import Volume
8
8
  from .models.network import Network
9
- from .models.container import Container, Env, Label, Port, Mount, NetworkSetting
9
+ from .models.container import (
10
+ Container,
11
+ Env,
12
+ Label,
13
+ Port,
14
+ Mount,
15
+ Bind,
16
+ NetworkSetting,
17
+ )
10
18
  from .models.registry import Registry
11
19
  from .templatetags.host import remove_password
12
20
 
@@ -211,6 +219,11 @@ class ContainerTable(NetBoxTable):
211
219
  url_params={"container_id": "pk"},
212
220
  verbose_name="Mounts count",
213
221
  )
222
+ bind_count = columns.LinkedCountColumn(
223
+ viewname="plugins:netbox_docker_plugin:bind_list",
224
+ url_params={"container_id": "pk"},
225
+ verbose_name="Binds count",
226
+ )
214
227
  networksetting_count = columns.LinkedCountColumn(
215
228
  viewname="plugins:netbox_docker_plugin:networksetting_list",
216
229
  url_params={"container_id": "pk"},
@@ -244,6 +257,7 @@ class ContainerTable(NetBoxTable):
244
257
  "hostname",
245
258
  "port_count",
246
259
  "mount_count",
260
+ "bind_count",
247
261
  "networksetting_count",
248
262
  "env_count",
249
263
  "label_count",
@@ -256,6 +270,7 @@ class ContainerTable(NetBoxTable):
256
270
  "state",
257
271
  "port_count",
258
272
  "mount_count",
273
+ "bind_count",
259
274
  "networksetting_count",
260
275
  "env_count",
261
276
  "label_count",
@@ -323,6 +338,21 @@ class MountTable(NetBoxTable):
323
338
  default_columns = ("container", "source", "volume")
324
339
 
325
340
 
341
+ class BindTable(NetBoxTable):
342
+ """Bind Table definition class"""
343
+
344
+ container = tables.Column(linkify=True)
345
+
346
+ actions = columns.ActionsColumn(actions=("edit", "delete"))
347
+
348
+ class Meta(NetBoxTable.Meta):
349
+ """Bind Table definition Meta class"""
350
+
351
+ model = Bind
352
+ fields = ("container", "host_path", "container_path")
353
+ default_columns = ("container", "host_path", "container_path")
354
+
355
+
326
356
  class NetworkSettingTable(NetBoxTable):
327
357
  """NetworkSetting Table definition class"""
328
358
 
@@ -111,6 +111,20 @@
111
111
  </div>
112
112
  {% endif %}
113
113
  </div>
114
+ <div class="card">
115
+ <h5 class="card-header">BINDS</h5>
116
+ <div class="card-body htmx-container table-responsive"
117
+ hx-get="{% url 'plugins:netbox_docker_plugin:bind_list' %}?container_id={{ object.pk }}"
118
+ hx-trigger="load"
119
+ ></div>
120
+ {% if perms.netbox_docker_plugin.add_env %}
121
+ <div class="card-footer text-end noprint">
122
+ <a href="{% url 'plugins:netbox_docker_plugin:bind_add' %}?container={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-primary btn-sm">
123
+ <i class="mdi mdi-plus-thick" aria-hidden="true"></i> New Bind
124
+ </a>
125
+ </div>
126
+ {% endif %}
127
+ </div>
114
128
  <div class="card">
115
129
  <h5 class="card-header">NETWORK SETTINGS</h5>
116
130
  <div class="card-body htmx-container table-responsive"
@@ -35,6 +35,7 @@ class ContainerApiTestCase(
35
35
  "env",
36
36
  "labels",
37
37
  "mounts",
38
+ "binds",
38
39
  "network_settings",
39
40
  ]
40
41
 
@@ -78,6 +79,9 @@ class ContainerApiTestCase(
78
79
  {"source": "/data", "volume": volume1.pk},
79
80
  {"source": "/etc", "volume": volume2.pk},
80
81
  ],
82
+ "binds": [
83
+ {"host_path": "/opt/ct5/data", "container_path": "/data"},
84
+ ],
81
85
  "network_settings": [
82
86
  {"network": network1.pk},
83
87
  ],
@@ -18,6 +18,7 @@ from .views import (
18
18
  label as label_views,
19
19
  port as port_views,
20
20
  mount as mount_views,
21
+ bind as bind_views,
21
22
  network_setting as network_setting_views,
22
23
  registry as registry_views,
23
24
  )
@@ -306,6 +307,27 @@ urlpatterns = (
306
307
  mount_views.MountDeleteView.as_view(),
307
308
  name="mount_delete",
308
309
  ),
310
+ # Bind
311
+ path(
312
+ "binds/",
313
+ bind_views.BindListView.as_view(),
314
+ name="bind_list",
315
+ ),
316
+ path(
317
+ "binds/add/",
318
+ bind_views.BindEditView.as_view(),
319
+ name="bind_add",
320
+ ),
321
+ path(
322
+ "binds/<int:pk>/edit/",
323
+ bind_views.BindEditView.as_view(),
324
+ name="bind_edit",
325
+ ),
326
+ path(
327
+ "binds/<int:pk>/delete/",
328
+ bind_views.BindDeleteView.as_view(),
329
+ name="bind_delete",
330
+ ),
309
331
  # NetworkSetting
310
332
  path(
311
333
  "network-settings/",
@@ -0,0 +1,28 @@
1
+ """Container views definitions"""
2
+
3
+ from netbox.views import generic
4
+ from .. import tables, filtersets
5
+ from ..forms.bind import BindForm, BindFilterForm
6
+ from ..models.container import Bind
7
+
8
+
9
+ class BindListView(generic.ObjectListView):
10
+ """Bind list view definition"""
11
+
12
+ queryset = Bind.objects.prefetch_related("container")
13
+ table = tables.BindTable
14
+ filterset = filtersets.BindFilterSet
15
+ filterset_form = BindFilterForm
16
+
17
+
18
+ class BindEditView(generic.ObjectEditView):
19
+ """Bind edition view definition"""
20
+
21
+ queryset = Bind.objects.all()
22
+ form = BindForm
23
+
24
+
25
+ class BindDeleteView(generic.ObjectDeleteView):
26
+ """Bind delete view definition"""
27
+
28
+ queryset = Bind.objects.all()
@@ -4,14 +4,29 @@ from utilities.utils import count_related
4
4
  from netbox.views import generic
5
5
  from .. import tables, filtersets
6
6
  from ..forms import container
7
- from ..models.container import Container, Mount, Port, NetworkSetting, Env, Label
7
+ from ..models.container import (
8
+ Container,
9
+ Mount,
10
+ Bind,
11
+ Port,
12
+ NetworkSetting,
13
+ Env,
14
+ Label,
15
+ )
8
16
 
9
17
 
10
18
  class ContainerView(generic.ObjectView):
11
19
  """Container view definition"""
12
20
 
13
21
  queryset = Container.objects.prefetch_related(
14
- "host", "image", "env", "labels", "mounts", "ports", "network_settings"
22
+ "host",
23
+ "image",
24
+ "env",
25
+ "labels",
26
+ "mounts",
27
+ "binds",
28
+ "ports",
29
+ "network_settings",
15
30
  )
16
31
 
17
32
 
@@ -28,6 +43,7 @@ class ContainerListView(generic.ObjectListView):
28
43
  queryset = Container.objects.annotate(
29
44
  port_count=count_related(Port, "container"),
30
45
  mount_count=count_related(Mount, "container"),
46
+ bind_count=count_related(Bind, "container"),
31
47
  networksetting_count=count_related(NetworkSetting, "container"),
32
48
  env_count=count_related(Env, "container"),
33
49
  label_count=count_related(Label, "container"),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: netbox-docker-plugin
3
- Version: 1.3.0
3
+ Version: 1.4.0
4
4
  Summary: Manage Docker with Netbox & style.
5
5
  Author-email: Vincent Simonin <vincent@saashup.com>
6
6
  Project-URL: Homepage, https://github.com/SaaShup/netbox-docker-plugin
@@ -16,6 +16,7 @@ netbox_docker_plugin/api/serializers.py
16
16
  netbox_docker_plugin/api/urls.py
17
17
  netbox_docker_plugin/api/views.py
18
18
  netbox_docker_plugin/forms/__init__.py
19
+ netbox_docker_plugin/forms/bind.py
19
20
  netbox_docker_plugin/forms/container.py
20
21
  netbox_docker_plugin/forms/env.py
21
22
  netbox_docker_plugin/forms/host.py
@@ -48,6 +49,7 @@ netbox_docker_plugin/migrations/0018_alter_mount_volume_alter_networksetting_net
48
49
  netbox_docker_plugin/migrations/0019_host_agent_version_host_docker_api_version.py
49
50
  netbox_docker_plugin/migrations/0020_container_hostname.py
50
51
  netbox_docker_plugin/migrations/0021_registry_and_more.py
52
+ netbox_docker_plugin/migrations/0022_bind_bind_netbox_docker_plugin_bind_unique_bind.py
51
53
  netbox_docker_plugin/migrations/__init__.py
52
54
  netbox_docker_plugin/models/__init__.py
53
55
  netbox_docker_plugin/models/container.py
@@ -90,6 +92,7 @@ netbox_docker_plugin/tests/volume/test_volume_api.py
90
92
  netbox_docker_plugin/tests/volume/test_volume_views.py
91
93
  netbox_docker_plugin/utilities/__init__.py
92
94
  netbox_docker_plugin/views/__init__.py
95
+ netbox_docker_plugin/views/bind.py
93
96
  netbox_docker_plugin/views/container.py
94
97
  netbox_docker_plugin/views/env.py
95
98
  netbox_docker_plugin/views/host.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "netbox-docker-plugin"
7
- version = "1.3.0"
7
+ version = "1.4.0"
8
8
  authors = [
9
9
  { name="Vincent Simonin", email="vincent@saashup.com" },
10
10
  ]