netbox-docker-plugin 5.1.0__tar.gz → 5.1.1__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 (146) hide show
  1. {netbox_docker_plugin-5.1.0/netbox_docker_plugin.egg-info → netbox_docker_plugin-5.1.1}/PKG-INFO +5 -1
  2. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/__init__.py +1 -1
  3. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/models/container.py +17 -3
  4. netbox_docker_plugin-5.1.1/netbox_docker_plugin/tests/container/test_container_delete.py +137 -0
  5. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/container.py +60 -1
  6. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1/netbox_docker_plugin.egg-info}/PKG-INFO +5 -1
  7. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin.egg-info/SOURCES.txt +2 -0
  8. netbox_docker_plugin-5.1.1/netbox_docker_plugin.egg-info/requires.txt +5 -0
  9. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/pyproject.toml +7 -1
  10. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/LICENSE +0 -0
  11. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/MANIFEST.in +0 -0
  12. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/README.md +0 -0
  13. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/api/__init__.py +0 -0
  14. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/api/renderers.py +0 -0
  15. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/api/serializers.py +0 -0
  16. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/api/urls.py +0 -0
  17. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/api/views.py +0 -0
  18. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/filtersets.py +0 -0
  19. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/__init__.py +0 -0
  20. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/bind.py +0 -0
  21. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/container.py +0 -0
  22. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/device.py +0 -0
  23. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/env.py +0 -0
  24. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/host.py +0 -0
  25. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/image.py +0 -0
  26. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/label.py +0 -0
  27. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/log_driver_option.py +0 -0
  28. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/mount.py +0 -0
  29. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/network.py +0 -0
  30. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/network_setting.py +0 -0
  31. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/port.py +0 -0
  32. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/registry.py +0 -0
  33. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/sysctl.py +0 -0
  34. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/forms/volume.py +0 -0
  35. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0001_initial.py +0 -0
  36. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0002_image.py +0 -0
  37. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0003_image_size.py +0 -0
  38. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0004_volume.py +0 -0
  39. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0005_network.py +0 -0
  40. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0006_container_port_mount_label_env_and_more.py +0 -0
  41. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0007_remove_container_netbox_docker_plugin_container_unique_name_host__and_more.py +0 -0
  42. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0008_alter_network_unique_together_network_networkid_and_more.py +0 -0
  43. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0009_remove_container_network_networksettings_and_more.py +0 -0
  44. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0010_container_containerid_and_more.py +0 -0
  45. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0011_host_token.py +0 -0
  46. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0012_host_state.py +0 -0
  47. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0013_host_netbox_url.py +0 -0
  48. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0014_container_operation.py +0 -0
  49. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0015_remove_mount_netbox_docker_plugin_mount_unique_volume_and_more.py +0 -0
  50. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0016_alter_env_value.py +0 -0
  51. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0017_network_state.py +0 -0
  52. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0018_alter_mount_volume_alter_networksetting_network.py +0 -0
  53. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0019_host_agent_version_host_docker_api_version.py +0 -0
  54. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0020_container_hostname.py +0 -0
  55. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0021_registry_and_more.py +0 -0
  56. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0022_bind_bind_netbox_docker_plugin_bind_unique_bind.py +0 -0
  57. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0023_delete_hosts.py +0 -0
  58. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0024_registry_host_alter_registry_name_and_more.py +0 -0
  59. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0025_alter_image_version.py +0 -0
  60. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0026_image_digest.py +0 -0
  61. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0027_container_restart_policy.py +0 -0
  62. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0028_mount_and_bind_read_only.py +0 -0
  63. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0029_alter_container_state.py +0 -0
  64. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0030_alter_container_containerid_alter_container_hostname_and_more.py +0 -0
  65. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0031_container_cap_add.py +0 -0
  66. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0032_device_and_more.py +0 -0
  67. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0033_host_operation.py +0 -0
  68. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0034_volume_max_size.py +0 -0
  69. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0035_container_log_driver_logdriveroption.py +0 -0
  70. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0036_alter_container_log_driver.py +0 -0
  71. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0037_alter_env_value.py +0 -0
  72. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/0038_container_cmd.py +0 -0
  73. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/1039_alter_port_public_port.py +0 -0
  74. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/1040_alter_container_log_driver.py +0 -0
  75. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/1041_sysctl.py +0 -0
  76. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/1042_registry_username_max_length.py +0 -0
  77. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/1043_container_cap_drop_container_extra_hosts_and_more.py +0 -0
  78. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/migrations/__init__.py +0 -0
  79. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/models/__init__.py +0 -0
  80. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/models/host.py +0 -0
  81. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/models/image.py +0 -0
  82. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/models/network.py +0 -0
  83. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/models/registry.py +0 -0
  84. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/models/volume.py +0 -0
  85. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/navigation.py +0 -0
  86. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/signals.py +0 -0
  87. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tables.py +0 -0
  88. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/templates/netbox_docker_plugin/container-exec.html +0 -0
  89. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/templates/netbox_docker_plugin/container-layout.html +0 -0
  90. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/templates/netbox_docker_plugin/container-logs.html +0 -0
  91. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/templates/netbox_docker_plugin/container.html +0 -0
  92. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/templates/netbox_docker_plugin/host-graph.html +0 -0
  93. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/templates/netbox_docker_plugin/host.html +0 -0
  94. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/templates/netbox_docker_plugin/image.html +0 -0
  95. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/templates/netbox_docker_plugin/network.html +0 -0
  96. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/templates/netbox_docker_plugin/registry.html +0 -0
  97. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/templates/netbox_docker_plugin/volume.html +0 -0
  98. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/templatetags/__init__.py +0 -0
  99. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/templatetags/host.py +0 -0
  100. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/__init__.py +0 -0
  101. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/base.py +0 -0
  102. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/container/__init__.py +0 -0
  103. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/container/test_container_actions.py +0 -0
  104. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/container/test_container_api.py +0 -0
  105. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/container/test_container_api_exec.py +0 -0
  106. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/container/test_container_operation_view.py +0 -0
  107. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/container/test_container_validation.py +0 -0
  108. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/container/test_container_views.py +0 -0
  109. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/host/__init__.py +0 -0
  110. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/host/test_host_api.py +0 -0
  111. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/host/test_host_views.py +0 -0
  112. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/host/test_replace_password.py +0 -0
  113. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/image/__init__.py +0 -0
  114. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/image/test_force_pull_image_with_special_cf.py +0 -0
  115. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/image/test_image_api.py +0 -0
  116. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/image/test_image_views.py +0 -0
  117. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/network/__init__.py +0 -0
  118. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/network/test_network_api.py +0 -0
  119. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/network/test_network_views.py +0 -0
  120. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/registry/__init__.py +0 -0
  121. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/registry/test_registry_api.py +0 -0
  122. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/registry/test_registry_views.py +0 -0
  123. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/test_init.py +0 -0
  124. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/volume/__init__.py +0 -0
  125. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/volume/test_volume_api.py +0 -0
  126. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/tests/volume/test_volume_views.py +0 -0
  127. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/urls.py +0 -0
  128. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/utilities/__init__.py +0 -0
  129. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/__init__.py +0 -0
  130. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/bind.py +0 -0
  131. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/device.py +0 -0
  132. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/env.py +0 -0
  133. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/host.py +0 -0
  134. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/image.py +0 -0
  135. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/label.py +0 -0
  136. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/log_driver_option.py +0 -0
  137. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/mount.py +0 -0
  138. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/network.py +0 -0
  139. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/network_setting.py +0 -0
  140. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/port.py +0 -0
  141. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/registry.py +0 -0
  142. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/sysctl.py +0 -0
  143. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin/views/volume.py +0 -0
  144. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin.egg-info/dependency_links.txt +0 -0
  145. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/netbox_docker_plugin.egg-info/top_level.txt +0 -0
  146. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.1.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: netbox-docker-plugin
3
- Version: 5.1.0
3
+ Version: 5.1.1
4
4
  Summary: Manage Docker with Netbox & style.
5
5
  Author-email: Vincent Simonin <vincent@saashup.com>, David Delassus <david.jose.delassus@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/SaaShup/netbox-docker-plugin
@@ -10,6 +10,10 @@ Classifier: Programming Language :: Python :: 3
10
10
  Requires-Python: >=3.12
11
11
  Description-Content-Type: text/markdown
12
12
  License-File: LICENSE
13
+ Provides-Extra: dev
14
+ Requires-Dist: requests-mock; extra == "dev"
15
+ Requires-Dist: coverage; extra == "dev"
16
+ Requires-Dist: pylint; extra == "dev"
13
17
  Dynamic: license-file
14
18
 
15
19
  # Netbox Docker Plugin
@@ -11,7 +11,7 @@ class NetBoxDockerConfig(PluginConfig):
11
11
  name = "netbox_docker_plugin"
12
12
  verbose_name = " NetBox Docker Plugin"
13
13
  description = "Manage Docker"
14
- version = "5.1.0"
14
+ version = "5.1.1"
15
15
  base_url = "docker"
16
16
  min_version = "4.5.0"
17
17
  author = "Vincent Simonin <vincent@saashup.com>, David Delassus <david.jose.delassus@gmail.com>"
@@ -2,17 +2,19 @@
2
2
 
3
3
  # pylint: disable=E1101
4
4
 
5
+ from django.contrib.contenttypes.models import ContentType
5
6
  from django.contrib.postgres.fields import ArrayField
6
7
  from django.core.exceptions import ValidationError
7
- from django.db import models
8
- from django.db.models.functions import Lower
9
- from django.urls import reverse
10
8
  from django.core.validators import (
11
9
  MinLengthValidator,
12
10
  MaxLengthValidator,
13
11
  MinValueValidator,
14
12
  MaxValueValidator,
15
13
  )
14
+ from django.db import models
15
+ from django.db.models.functions import Lower
16
+ from django.urls import reverse
17
+ from extras.models import JournalEntry
16
18
  from utilities.choices import ChoiceSet
17
19
  from utilities.querysets import RestrictedQuerySet
18
20
  from netbox.models import NetBoxModel
@@ -306,6 +308,18 @@ class Container(NetBoxModel):
306
308
  ),
307
309
  )
308
310
 
311
+ def delete(self, using=None, keep_parents=False):
312
+ ct = ContentType.objects.get_for_model(self)
313
+ qs = JournalEntry.objects.filter(
314
+ assigned_object_type=ct,
315
+ assigned_object_id=self.pk,
316
+ )
317
+ # _raw_delete issues a single SQL DELETE bypassing Django's Collector,
318
+ # avoiding per-row post_delete signals (ObjectChange writes) that make
319
+ # bulk journal cleanup O(n) slow.
320
+ qs._raw_delete(qs.db) # pylint: disable=protected-access
321
+ return super().delete(using, keep_parents)
322
+
309
323
  def __str__(self):
310
324
  return f"{self.name}"
311
325
 
@@ -0,0 +1,137 @@
1
+ """Container deletion tests — journal entry cleanup"""
2
+
3
+ import time
4
+
5
+ from django.contrib.contenttypes.models import ContentType
6
+ from django.test import TestCase
7
+
8
+ from extras.models import JournalEntry
9
+ from netbox_docker_plugin.models.container import Container
10
+ from netbox_docker_plugin.models.host import Host
11
+ from netbox_docker_plugin.models.image import Image
12
+ from netbox_docker_plugin.models.registry import Registry
13
+
14
+
15
+ def _make_journal_entries(container, count):
16
+ ct = ContentType.objects.get_for_model(Container)
17
+ batch_size = 10000
18
+ for start in range(0, count, batch_size):
19
+ JournalEntry.objects.bulk_create(
20
+ [
21
+ JournalEntry(
22
+ assigned_object_type=ct,
23
+ assigned_object_id=container.pk,
24
+ created_by=None,
25
+ kind="info",
26
+ comments=f"entry {start + i}",
27
+ )
28
+ for i in range(min(batch_size, count - start))
29
+ ]
30
+ )
31
+
32
+
33
+ class ContainerDeleteJournalTestCase(TestCase):
34
+ """Verify that container deletion cleans up journal entries in batches."""
35
+
36
+ @classmethod
37
+ def setUpTestData(cls):
38
+ cls.host = Host.objects.create(endpoint="http://localhost:8080", name="host1")
39
+ cls.registry = Registry.objects.create(
40
+ host=cls.host,
41
+ name="registry1",
42
+ serveraddress="http://localhost:8080",
43
+ )
44
+ cls.image = Image.objects.create(
45
+ host=cls.host, name="image1", registry=cls.registry
46
+ )
47
+
48
+ def _make_container(self, name="container1", state="exited"):
49
+ """Create and return a Container in the given state."""
50
+ return Container.objects.create(
51
+ host=self.host,
52
+ image=self.image,
53
+ name=name,
54
+ operation="none",
55
+ state=state,
56
+ )
57
+
58
+ def test_delete_container_with_no_journal_entries(self):
59
+ """Container with no journal entries can be deleted without errors."""
60
+ container = self._make_container()
61
+ pk = container.pk
62
+ t0 = time.monotonic()
63
+ container.delete()
64
+ print(
65
+ f"Deleted container (0 journal entries) in {(time.monotonic() - t0) * 1000:.1f}ms"
66
+ )
67
+
68
+ self.assertFalse(Container.objects.filter(pk=pk).exists())
69
+
70
+ def test_delete_container_removes_journal_entries(self):
71
+ """Journal entries linked to the deleted container are removed."""
72
+ container = self._make_container(name="container2")
73
+ _make_journal_entries(container, 5)
74
+ ct = ContentType.objects.get_for_model(Container)
75
+
76
+ self.assertEqual(
77
+ JournalEntry.objects.filter(
78
+ assigned_object_type=ct, assigned_object_id=container.pk
79
+ ).count(),
80
+ 5,
81
+ )
82
+
83
+ pk = container.pk
84
+ t0 = time.monotonic()
85
+ container.delete()
86
+ print(
87
+ f"Deleted container (5 journal entries) in {(time.monotonic() - t0) * 1000:.1f}ms"
88
+ )
89
+
90
+ self.assertFalse(Container.objects.filter(pk=pk).exists())
91
+ self.assertEqual(
92
+ JournalEntry.objects.filter(
93
+ assigned_object_type=ct, assigned_object_id=pk
94
+ ).count(),
95
+ 0,
96
+ )
97
+
98
+ def test_delete_container_removes_many_journal_entries(self):
99
+ """Deletion removes all journal entries regardless of count."""
100
+ container = self._make_container(name="container3")
101
+ _make_journal_entries(container, 500000)
102
+ ct = ContentType.objects.get_for_model(Container)
103
+
104
+ pk = container.pk
105
+ t0 = time.monotonic()
106
+ container.delete()
107
+ elapsed = (time.monotonic() - t0) * 1000
108
+ print(f"Deleted container (500000 journal entries) in {elapsed:.1f}ms")
109
+
110
+ self.assertFalse(Container.objects.filter(pk=pk).exists())
111
+ self.assertEqual(
112
+ JournalEntry.objects.filter(
113
+ assigned_object_type=ct, assigned_object_id=pk
114
+ ).count(),
115
+ 0,
116
+ )
117
+
118
+ def test_delete_does_not_remove_journal_entries_of_other_containers(self):
119
+ """Deleting one container must not remove journal entries of another."""
120
+ container_a = self._make_container(name="container4a")
121
+ container_b = self._make_container(name="container4b")
122
+ _make_journal_entries(container_a, 3)
123
+ _make_journal_entries(container_b, 3)
124
+ ct = ContentType.objects.get_for_model(Container)
125
+
126
+ t0 = time.monotonic()
127
+ container_a.delete()
128
+ print(
129
+ f"Deleted container (3 journal entries) in {(time.monotonic() - t0) * 1000:.1f}ms"
130
+ )
131
+
132
+ self.assertEqual(
133
+ JournalEntry.objects.filter(
134
+ assigned_object_type=ct, assigned_object_id=container_b.pk
135
+ ).count(),
136
+ 3,
137
+ )
@@ -1,5 +1,9 @@
1
1
  """Container views definitions"""
2
2
 
3
+ from collections import defaultdict
4
+ from django.db import router
5
+ from django.db.models.deletion import Collector
6
+ from extras.models import JournalEntry
3
7
  from utilities.query import count_related
4
8
  from utilities.views import ViewTab, register_model_view
5
9
  from netbox.views import generic
@@ -125,11 +129,66 @@ class ContainerBulkDeleteView(generic.BulkDeleteView):
125
129
  table = tables.ContainerTable
126
130
 
127
131
 
132
+ class _JournalEntryCount:
133
+ """Proxy passed to the deletion template in place of a full JournalEntry list.
134
+
135
+ The template calls len() for the accordion header count, then iterates to
136
+ render individual rows. This object answers len() with a single COUNT query
137
+ and yields nothing on iteration, avoiding fetching hundreds of thousands of
138
+ rows just to display a number."""
139
+
140
+ def __init__(self, queryset):
141
+ self._queryset = queryset
142
+ self._count = None
143
+
144
+ def __len__(self):
145
+ if self._count is None:
146
+ self._count = self._queryset.count()
147
+ return self._count
148
+
149
+ def __iter__(self):
150
+ return iter([])
151
+
152
+ def __bool__(self):
153
+ return len(self) > 0
154
+
155
+
128
156
  class ContainerDeleteView(generic.ObjectDeleteView):
129
157
  """Container delete view definition"""
130
158
 
131
159
  default_return_url = "plugins:netbox_docker_plugin:container_list"
132
- queryset = Container.objects.all()
160
+ queryset = Container.objects.select_related("host", "image")
161
+
162
+ def _get_dependent_objects(self, obj):
163
+ class SkipJournalCollector(Collector):
164
+ """Collector that skips JournalEntry to avoid a slow full scan."""
165
+
166
+ def collect(self, objs, **kwargs): # pylint: disable=arguments-differ
167
+ if getattr(objs, "model", None) is JournalEntry:
168
+ return
169
+ super().collect(objs, **kwargs)
170
+
171
+ using = router.db_for_write(obj._meta.model)
172
+ collector = SkipJournalCollector(using=using)
173
+ collector.collect([obj])
174
+
175
+ dependent_objects = defaultdict(list)
176
+ for model, instances in collector.instances_with_model():
177
+ if model._meta.auto_created:
178
+ continue
179
+ if instances == obj:
180
+ continue
181
+ dependent_objects[model].append(instances)
182
+
183
+ journal_qs = JournalEntry.objects.filter(
184
+ assigned_object_type__app_label="netbox_docker_plugin",
185
+ assigned_object_type__model="container",
186
+ assigned_object_id=obj.pk,
187
+ )
188
+ if journal_qs.exists():
189
+ dependent_objects[JournalEntry] = _JournalEntryCount(journal_qs)
190
+
191
+ return dict(dependent_objects)
133
192
 
134
193
 
135
194
  class ContainerOperationView(generic.ObjectEditView):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: netbox-docker-plugin
3
- Version: 5.1.0
3
+ Version: 5.1.1
4
4
  Summary: Manage Docker with Netbox & style.
5
5
  Author-email: Vincent Simonin <vincent@saashup.com>, David Delassus <david.jose.delassus@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/SaaShup/netbox-docker-plugin
@@ -10,6 +10,10 @@ Classifier: Programming Language :: Python :: 3
10
10
  Requires-Python: >=3.12
11
11
  Description-Content-Type: text/markdown
12
12
  License-File: LICENSE
13
+ Provides-Extra: dev
14
+ Requires-Dist: requests-mock; extra == "dev"
15
+ Requires-Dist: coverage; extra == "dev"
16
+ Requires-Dist: pylint; extra == "dev"
13
17
  Dynamic: license-file
14
18
 
15
19
  # Netbox Docker Plugin
@@ -11,6 +11,7 @@ netbox_docker_plugin/urls.py
11
11
  netbox_docker_plugin.egg-info/PKG-INFO
12
12
  netbox_docker_plugin.egg-info/SOURCES.txt
13
13
  netbox_docker_plugin.egg-info/dependency_links.txt
14
+ netbox_docker_plugin.egg-info/requires.txt
14
15
  netbox_docker_plugin.egg-info/top_level.txt
15
16
  netbox_docker_plugin/api/__init__.py
16
17
  netbox_docker_plugin/api/renderers.py
@@ -103,6 +104,7 @@ netbox_docker_plugin/tests/container/__init__.py
103
104
  netbox_docker_plugin/tests/container/test_container_actions.py
104
105
  netbox_docker_plugin/tests/container/test_container_api.py
105
106
  netbox_docker_plugin/tests/container/test_container_api_exec.py
107
+ netbox_docker_plugin/tests/container/test_container_delete.py
106
108
  netbox_docker_plugin/tests/container/test_container_operation_view.py
107
109
  netbox_docker_plugin/tests/container/test_container_validation.py
108
110
  netbox_docker_plugin/tests/container/test_container_views.py
@@ -0,0 +1,5 @@
1
+
2
+ [dev]
3
+ requests-mock
4
+ coverage
5
+ pylint
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "netbox-docker-plugin"
7
- version = "5.1.0"
7
+ version = "5.1.1"
8
8
  authors = [
9
9
  { name="Vincent Simonin", email="vincent@saashup.com" },
10
10
  { name="David Delassus", email="david.jose.delassus@gmail.com" }
@@ -16,6 +16,12 @@ classifiers = [
16
16
  "Programming Language :: Python :: 3",
17
17
  ]
18
18
  keywords = ["netbox", "netbox-plugin", "docker"]
19
+ [project.optional-dependencies]
20
+ dev = [
21
+ "requests-mock",
22
+ "coverage",
23
+ "pylint",
24
+ ]
19
25
 
20
26
  [project.urls]
21
27
  "Homepage" = "https://github.com/SaaShup/netbox-docker-plugin"