netbox-docker-plugin 1.3.1__tar.gz → 1.5.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 (111) hide show
  1. {netbox-docker-plugin-1.3.1/netbox_docker_plugin.egg-info → netbox-docker-plugin-1.5.0}/PKG-INFO +1 -1
  2. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/__init__.py +1 -1
  3. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/api/serializers.py +44 -1
  4. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/api/views.py +13 -3
  5. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/filtersets.py +30 -1
  6. netbox-docker-plugin-1.5.0/netbox_docker_plugin/forms/bind.py +46 -0
  7. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/forms/image.py +15 -1
  8. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/forms/registry.py +8 -1
  9. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0021_registry_and_more.py +0 -2
  10. netbox-docker-plugin-1.5.0/netbox_docker_plugin/migrations/0022_bind_bind_netbox_docker_plugin_bind_unique_bind.py +74 -0
  11. netbox-docker-plugin-1.5.0/netbox_docker_plugin/migrations/0023_delete_hosts.py +33 -0
  12. netbox-docker-plugin-1.5.0/netbox_docker_plugin/migrations/0024_registry_host_alter_registry_name_and_more.py +47 -0
  13. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/models/container.py +38 -0
  14. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/models/image.py +0 -1
  15. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/models/registry.py +23 -11
  16. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tables.py +31 -1
  17. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/templates/netbox_docker_plugin/container.html +14 -0
  18. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/templates/netbox_docker_plugin/host.html +17 -0
  19. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/templates/netbox_docker_plugin/registry.html +4 -0
  20. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/container/test_container_api.py +14 -2
  21. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/container/test_container_operation_view.py +10 -2
  22. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/container/test_container_validation.py +14 -2
  23. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/container/test_container_views.py +10 -2
  24. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/host/test_host_api.py +41 -0
  25. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/registry/test_registry_api.py +21 -7
  26. netbox-docker-plugin-1.5.0/netbox_docker_plugin/tests/registry/test_registry_views.py +39 -0
  27. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/urls.py +22 -0
  28. netbox-docker-plugin-1.5.0/netbox_docker_plugin/views/bind.py +28 -0
  29. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/views/container.py +18 -2
  30. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/views/host.py +7 -1
  31. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0/netbox_docker_plugin.egg-info}/PKG-INFO +1 -1
  32. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin.egg-info/SOURCES.txt +5 -0
  33. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/pyproject.toml +1 -1
  34. netbox-docker-plugin-1.3.1/netbox_docker_plugin/tests/registry/test_registry_views.py +0 -33
  35. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/LICENSE +0 -0
  36. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/MANIFEST.in +0 -0
  37. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/README.md +0 -0
  38. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/api/__init__.py +0 -0
  39. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/api/urls.py +0 -0
  40. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/forms/__init__.py +0 -0
  41. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/forms/container.py +0 -0
  42. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/forms/env.py +0 -0
  43. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/forms/host.py +0 -0
  44. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/forms/label.py +0 -0
  45. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/forms/mount.py +0 -0
  46. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/forms/network.py +0 -0
  47. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/forms/network_setting.py +0 -0
  48. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/forms/port.py +0 -0
  49. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/forms/volume.py +0 -0
  50. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0001_initial.py +0 -0
  51. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0002_image.py +0 -0
  52. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0003_image_size.py +0 -0
  53. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0004_volume.py +0 -0
  54. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0005_network.py +0 -0
  55. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0006_container_port_mount_label_env_and_more.py +0 -0
  56. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0007_remove_container_netbox_docker_plugin_container_unique_name_host__and_more.py +0 -0
  57. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0008_alter_network_unique_together_network_networkid_and_more.py +0 -0
  58. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0009_remove_container_network_networksettings_and_more.py +0 -0
  59. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0010_container_containerid_and_more.py +0 -0
  60. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0011_host_token.py +0 -0
  61. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0012_host_state.py +0 -0
  62. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0013_host_netbox_url.py +0 -0
  63. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0014_container_operation.py +0 -0
  64. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0015_remove_mount_netbox_docker_plugin_mount_unique_volume_and_more.py +0 -0
  65. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0016_alter_env_value.py +0 -0
  66. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0017_network_state.py +0 -0
  67. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0018_alter_mount_volume_alter_networksetting_network.py +0 -0
  68. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0019_host_agent_version_host_docker_api_version.py +0 -0
  69. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/0020_container_hostname.py +0 -0
  70. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/migrations/__init__.py +0 -0
  71. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/models/__init__.py +0 -0
  72. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/models/host.py +0 -0
  73. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/models/network.py +0 -0
  74. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/models/volume.py +0 -0
  75. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/navigation.py +0 -0
  76. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/templates/netbox_docker_plugin/image.html +0 -0
  77. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/templates/netbox_docker_plugin/network.html +0 -0
  78. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/templates/netbox_docker_plugin/volume.html +0 -0
  79. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/templatetags/__init__.py +0 -0
  80. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/templatetags/host.py +0 -0
  81. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/__init__.py +0 -0
  82. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/base.py +0 -0
  83. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/container/__init__.py +0 -0
  84. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/host/__init__.py +0 -0
  85. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/host/test_host_views.py +0 -0
  86. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/host/test_replace_password.py +0 -0
  87. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/image/__init__.py +0 -0
  88. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/image/test_image_api.py +0 -0
  89. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/image/test_image_views.py +0 -0
  90. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/network/__init__.py +0 -0
  91. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/network/test_network_api.py +0 -0
  92. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/network/test_network_views.py +0 -0
  93. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/registry/__init__.py +0 -0
  94. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/test_init.py +0 -0
  95. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/volume/__init__.py +0 -0
  96. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/volume/test_volume_api.py +0 -0
  97. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/tests/volume/test_volume_views.py +0 -0
  98. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/utilities/__init__.py +0 -0
  99. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/views/__init__.py +0 -0
  100. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/views/env.py +0 -0
  101. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/views/image.py +0 -0
  102. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/views/label.py +0 -0
  103. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/views/mount.py +0 -0
  104. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/views/network.py +0 -0
  105. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/views/network_setting.py +0 -0
  106. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/views/port.py +0 -0
  107. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/views/registry.py +0 -0
  108. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin/views/volume.py +0 -0
  109. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin.egg-info/dependency_links.txt +0 -0
  110. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.0}/netbox_docker_plugin.egg-info/top_level.txt +0 -0
  111. {netbox-docker-plugin-1.3.1 → netbox-docker-plugin-1.5.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.1
3
+ Version: 1.5.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.1"
13
+ version = "1.5.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
 
@@ -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:
@@ -462,6 +501,7 @@ class RegistrySerializer(NetBoxModelSerializer):
462
501
  url = serializers.HyperlinkedIdentityField(
463
502
  view_name="plugins-api:netbox_docker_plugin-api:registry-detail"
464
503
  )
504
+ host = NestedHostSerializer()
465
505
  images = NestedImageSerializer(many=True, read_only=True)
466
506
 
467
507
  class Meta:
@@ -472,6 +512,7 @@ class RegistrySerializer(NetBoxModelSerializer):
472
512
  "id",
473
513
  "name",
474
514
  "url",
515
+ "host",
475
516
  "display",
476
517
  "serveraddress",
477
518
  "username",
@@ -491,6 +532,7 @@ class HostSerializer(NetBoxModelSerializer):
491
532
  volumes = NestedVolumeSerializer(many=True, read_only=True)
492
533
  networks = NestedNetworkSerializer(many=True, read_only=True)
493
534
  containers = NestedContainerSerializer(many=True, read_only=True)
535
+ registries = NestedRegistrySerializer(many=True, read_only=True)
494
536
  token = NestedTokenSerializer(read_only=True)
495
537
 
496
538
  class Meta:
@@ -516,4 +558,5 @@ class HostSerializer(NetBoxModelSerializer):
516
558
  "volumes",
517
559
  "networks",
518
560
  "containers",
561
+ "registries",
519
562
  )
@@ -23,7 +23,9 @@ from ..models.registry import Registry
23
23
  class HostViewSet(NetBoxModelViewSet):
24
24
  """Host view set class"""
25
25
 
26
- queryset = Host.objects.prefetch_related("images", "volumes", "tags")
26
+ queryset = Host.objects.prefetch_related(
27
+ "images", "volumes", "networks", "containers", "registries", "tags"
28
+ )
27
29
  filterset_class = filtersets.HostFilterSet
28
30
  serializer_class = HostSerializer
29
31
  http_method_names = ["get", "post", "patch", "delete", "options"]
@@ -79,7 +81,15 @@ class ContainerViewSet(NetBoxModelViewSet):
79
81
  """Container view set class"""
80
82
 
81
83
  queryset = Container.objects.prefetch_related(
82
- "network_settings", "mounts", "env", "image", "host", "ports", "labels", "tags"
84
+ "network_settings",
85
+ "mounts",
86
+ "binds",
87
+ "env",
88
+ "image",
89
+ "host",
90
+ "ports",
91
+ "labels",
92
+ "tags",
83
93
  )
84
94
  filterset_class = filtersets.ContainerFilterSet
85
95
  serializer_class = ContainerSerializer
@@ -89,7 +99,7 @@ class ContainerViewSet(NetBoxModelViewSet):
89
99
  class RegistryViewSet(NetBoxModelViewSet):
90
100
  """Registry view set class"""
91
101
 
92
- queryset = Registry.objects.prefetch_related("images", "tags")
102
+ queryset = Registry.objects.prefetch_related("host", "images", "tags")
93
103
  filterset_class = filtersets.RegistryFilterSet
94
104
  serializer_class = RegistrySerializer
95
105
  http_method_names = ["get", "post", "patch", "delete", "options"]
@@ -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
 
@@ -41,6 +49,11 @@ class RegistryFilterSet(NetBoxModelFilterSet):
41
49
  """Registry filterset definition class"""
42
50
 
43
51
  name = filters.CharFilter(lookup_expr="icontains")
52
+ host_id = ModelMultipleChoiceFilter(
53
+ field_name="host_id",
54
+ queryset=Host.objects.all(),
55
+ label="Host (ID)",
56
+ )
44
57
 
45
58
  class Meta:
46
59
  """Registry filterset definition meta class"""
@@ -240,6 +253,22 @@ class MountFilterSet(BaseFilterSet):
240
253
  fields = ("id",)
241
254
 
242
255
 
256
+ class BindFilterSet(BaseFilterSet):
257
+ """Bind filterset definition class"""
258
+
259
+ container_id = ModelMultipleChoiceFilter(
260
+ field_name="container_id",
261
+ queryset=Container.objects.all(),
262
+ label="Container (ID)",
263
+ )
264
+
265
+ class Meta:
266
+ """Bind filterset definition meta class"""
267
+
268
+ model = Bind
269
+ fields = ("id",)
270
+
271
+
243
272
  class NetworkSettingFilterSet(BaseFilterSet):
244
273
  """NetworkSetting filterset definition class"""
245
274
 
@@ -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
+ )
@@ -1,7 +1,11 @@
1
1
  """Image Forms definitions"""
2
2
 
3
3
  from django import forms
4
- from utilities.forms.fields import TagFilterField, DynamicModelMultipleChoiceField
4
+ from utilities.forms.fields import (
5
+ TagFilterField,
6
+ DynamicModelMultipleChoiceField,
7
+ DynamicModelChoiceField,
8
+ )
5
9
  from netbox.forms import (
6
10
  NetBoxModelForm,
7
11
  NetBoxModelImportForm,
@@ -16,6 +20,16 @@ from ..models.registry import Registry
16
20
  class ImageForm(NetBoxModelForm):
17
21
  """Image form definition class"""
18
22
 
23
+ host = DynamicModelChoiceField(
24
+ label="Host", queryset=Host.objects.all(), required=True
25
+ )
26
+ registry = DynamicModelChoiceField(
27
+ label="Registry",
28
+ queryset=Registry.objects.all(),
29
+ required=True,
30
+ query_params={"host_id": "$host"},
31
+ )
32
+
19
33
  class Meta:
20
34
  """Image form definition Meta class"""
21
35
 
@@ -1,12 +1,13 @@
1
1
  """Registry Forms definitions"""
2
2
 
3
3
  from django import forms
4
- from utilities.forms.fields import TagFilterField
4
+ from utilities.forms.fields import TagFilterField, DynamicModelMultipleChoiceField
5
5
  from netbox.forms import (
6
6
  NetBoxModelForm,
7
7
  NetBoxModelFilterSetForm,
8
8
  )
9
9
  from ..models.registry import Registry
10
+ from ..models.host import Host
10
11
 
11
12
 
12
13
  class RegistryForm(NetBoxModelForm):
@@ -24,6 +25,7 @@ class RegistryForm(NetBoxModelForm):
24
25
 
25
26
  model = Registry
26
27
  fields = (
28
+ "host",
27
29
  "name",
28
30
  "serveraddress",
29
31
  "username",
@@ -39,5 +41,10 @@ class RegistryFilterForm(NetBoxModelFilterSetForm):
39
41
  """Registry filter form definition class"""
40
42
 
41
43
  model = Registry
44
+ host_id = DynamicModelMultipleChoiceField(
45
+ queryset=Host.objects.all(),
46
+ required=False,
47
+ label="Host",
48
+ )
42
49
  name = forms.CharField(label="Name", required=False)
43
50
  tag = TagFilterField(model)
@@ -6,7 +6,6 @@ import utilities.json
6
6
  import django.core.validators
7
7
  from django.db import migrations, models
8
8
  import django.db.models.deletion
9
- import netbox_docker_plugin.models.registry
10
9
 
11
10
 
12
11
  class Migration(migrations.Migration):
@@ -60,7 +59,6 @@ class Migration(migrations.Migration):
60
59
  model_name="image",
61
60
  name="registry",
62
61
  field=models.ForeignKey(
63
- default=netbox_docker_plugin.models.registry.Registry.get_default_registry,
64
62
  on_delete=django.db.models.deletion.CASCADE,
65
63
  related_name="images",
66
64
  to="netbox_docker_plugin.registry",
@@ -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
+ ]
@@ -0,0 +1,33 @@
1
+ # pylint: disable=C0103
2
+ """Migration file"""
3
+
4
+ from django.db import migrations
5
+
6
+
7
+ def delete_hosts(apps, schema_editor):
8
+ """Delete all Hosts and Registries"""
9
+ Host = apps.get_model("netbox_docker_plugin", "Host")
10
+ Host.objects.using(schema_editor.connection.alias).all().delete()
11
+
12
+ Registry = Host = apps.get_model("netbox_docker_plugin", "Registry")
13
+ Registry.objects.using(schema_editor.connection.alias).all().delete()
14
+
15
+
16
+ def do_nothing(apps, schema_editor): # pylint: disable=W0613
17
+ """Nothing to do"""
18
+ return None
19
+
20
+
21
+ class Migration(migrations.Migration):
22
+ """Migration file"""
23
+
24
+ dependencies = [
25
+ (
26
+ "netbox_docker_plugin",
27
+ "0022_bind_bind_netbox_docker_plugin_bind_unique_bind",
28
+ ),
29
+ ]
30
+
31
+ operations = [
32
+ migrations.RunPython(delete_hosts, do_nothing),
33
+ ]
@@ -0,0 +1,47 @@
1
+ # pylint: disable=C0103
2
+ """Migration file"""
3
+
4
+ import django.core.validators
5
+ from django.db import migrations, models
6
+ import django.db.models.deletion
7
+
8
+ class Migration(migrations.Migration):
9
+ """Migration file"""
10
+
11
+ dependencies = [
12
+ (
13
+ "netbox_docker_plugin",
14
+ "0023_delete_hosts",
15
+ ),
16
+ ]
17
+
18
+ operations = [
19
+ migrations.AddField(
20
+ model_name="registry",
21
+ name="host",
22
+ field=models.ForeignKey(
23
+ default=None,
24
+ on_delete=django.db.models.deletion.CASCADE,
25
+ related_name="registries",
26
+ to="netbox_docker_plugin.host",
27
+ ),
28
+ preserve_default=False,
29
+ ),
30
+ migrations.AlterField(
31
+ model_name="registry",
32
+ name="name",
33
+ field=models.CharField(
34
+ max_length=255,
35
+ validators=[
36
+ django.core.validators.MinLengthValidator(limit_value=1),
37
+ django.core.validators.MaxLengthValidator(limit_value=255),
38
+ ],
39
+ ),
40
+ ),
41
+ migrations.AddConstraint(
42
+ model_name="registry",
43
+ constraint=models.UniqueConstraint(
44
+ fields=("host", "name"), name="netbox_docker_plugin_registry_name_host"
45
+ ),
46
+ ),
47
+ ]
@@ -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
 
@@ -19,7 +19,6 @@ class Image(NetBoxModel):
19
19
  host = models.ForeignKey(Host, on_delete=models.CASCADE, related_name="images")
20
20
  registry = models.ForeignKey(
21
21
  Registry,
22
- default=Registry.get_default_registry, # type: ignore
23
22
  on_delete=models.CASCADE,
24
23
  related_name="images",
25
24
  )
@@ -1,19 +1,35 @@
1
1
  """Registry Model definition"""
2
2
 
3
3
  from django.db import models
4
+ from django.db.models.signals import post_save
5
+ from django.dispatch import receiver
4
6
  from django.core.validators import (
5
7
  MinLengthValidator,
6
8
  MaxLengthValidator,
7
9
  )
8
10
  from django.urls import reverse
9
11
  from netbox.models import NetBoxModel
12
+ from .host import Host
13
+
14
+
15
+ @receiver(post_save, sender=Host)
16
+ def create_default_registry(sender, **kwargs): # pylint: disable=W0613
17
+ """Create default registry on Host creation"""
18
+
19
+ if kwargs.get("created") is True:
20
+ registry = Registry(
21
+ host=kwargs.get("instance"),
22
+ name="dockerhub",
23
+ serveraddress="https://registry.hub.docker.com/v2/",
24
+ )
25
+ registry.save()
10
26
 
11
27
 
12
28
  class Registry(NetBoxModel):
13
29
  """Registry definition class"""
14
30
 
31
+ host = models.ForeignKey(Host, on_delete=models.CASCADE, related_name="registries")
15
32
  name = models.CharField(
16
- unique=True,
17
33
  max_length=255,
18
34
  validators=[
19
35
  MinLengthValidator(limit_value=1),
@@ -25,20 +41,16 @@ class Registry(NetBoxModel):
25
41
  password = models.CharField(blank=True, null=True, max_length=512)
26
42
  email = models.EmailField(blank=True, null=True, max_length=512)
27
43
 
28
- @classmethod
29
- def get_default_registry(cls):
30
- """Return the default Registry"""
31
- # pylint: disable=W0612
32
- registry, created = cls.objects.get_or_create(
33
- name="dockerhub",
34
- serveraddress="https://registry.hub.docker.com/v2/",
35
- )
36
- return registry.pk
37
-
38
44
  class Meta:
39
45
  """Registry Model Meta Class"""
40
46
 
41
47
  ordering = ("name",)
48
+ constraints = (
49
+ models.UniqueConstraint(
50
+ fields=["host", "name"],
51
+ name="%(app_label)s_%(class)s_name_host",
52
+ ),
53
+ )
42
54
 
43
55
  def __str__(self):
44
56
  return f"{self.name}"