netbox-docker-plugin 5.1.0__tar.gz → 5.2.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 (150) hide show
  1. {netbox_docker_plugin-5.1.0/netbox_docker_plugin.egg-info → netbox_docker_plugin-5.2.0}/PKG-INFO +5 -1
  2. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/__init__.py +1 -1
  3. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/api/serializers.py +3 -0
  4. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/api/views.py +8 -2
  5. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/filtersets.py +1 -0
  6. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/host.py +37 -1
  7. netbox_docker_plugin-5.2.0/netbox_docker_plugin/migrations/1044_host_virtual_machine.py +29 -0
  8. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/models/container.py +23 -3
  9. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/models/host.py +7 -0
  10. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tables.py +2 -0
  11. netbox_docker_plugin-5.2.0/netbox_docker_plugin/template_content.py +23 -0
  12. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/templates/netbox_docker_plugin/host.html +11 -0
  13. netbox_docker_plugin-5.2.0/netbox_docker_plugin/templates/netbox_docker_plugin/virtual_machine_host_table.html +4 -0
  14. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/container/test_container_api.py +25 -4
  15. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/container/test_container_api_exec.py +8 -3
  16. netbox_docker_plugin-5.2.0/netbox_docker_plugin/tests/container/test_container_delete.py +137 -0
  17. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/container/test_container_operation_view.py +6 -2
  18. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/container/test_container_validation.py +36 -0
  19. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/container/test_container_views.py +6 -2
  20. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/host/test_host_views.py +2 -2
  21. netbox_docker_plugin-5.2.0/netbox_docker_plugin/tests/host/test_host_virtual_machine.py +74 -0
  22. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/volume/test_volume_api.py +3 -1
  23. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/urls.py +1 -1
  24. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/container.py +60 -1
  25. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/host.py +15 -6
  26. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0/netbox_docker_plugin.egg-info}/PKG-INFO +5 -1
  27. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin.egg-info/SOURCES.txt +6 -0
  28. netbox_docker_plugin-5.2.0/netbox_docker_plugin.egg-info/requires.txt +5 -0
  29. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/pyproject.toml +7 -1
  30. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/LICENSE +0 -0
  31. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/MANIFEST.in +0 -0
  32. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/README.md +0 -0
  33. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/api/__init__.py +0 -0
  34. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/api/renderers.py +0 -0
  35. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/api/urls.py +0 -0
  36. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/__init__.py +0 -0
  37. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/bind.py +0 -0
  38. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/container.py +0 -0
  39. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/device.py +0 -0
  40. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/env.py +0 -0
  41. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/image.py +0 -0
  42. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/label.py +0 -0
  43. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/log_driver_option.py +0 -0
  44. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/mount.py +0 -0
  45. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/network.py +0 -0
  46. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/network_setting.py +0 -0
  47. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/port.py +0 -0
  48. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/registry.py +0 -0
  49. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/sysctl.py +0 -0
  50. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/forms/volume.py +0 -0
  51. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0001_initial.py +0 -0
  52. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0002_image.py +0 -0
  53. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0003_image_size.py +0 -0
  54. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0004_volume.py +0 -0
  55. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0005_network.py +0 -0
  56. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0006_container_port_mount_label_env_and_more.py +0 -0
  57. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0007_remove_container_netbox_docker_plugin_container_unique_name_host__and_more.py +0 -0
  58. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0008_alter_network_unique_together_network_networkid_and_more.py +0 -0
  59. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0009_remove_container_network_networksettings_and_more.py +0 -0
  60. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0010_container_containerid_and_more.py +0 -0
  61. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0011_host_token.py +0 -0
  62. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0012_host_state.py +0 -0
  63. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0013_host_netbox_url.py +0 -0
  64. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0014_container_operation.py +0 -0
  65. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0015_remove_mount_netbox_docker_plugin_mount_unique_volume_and_more.py +0 -0
  66. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0016_alter_env_value.py +0 -0
  67. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0017_network_state.py +0 -0
  68. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0018_alter_mount_volume_alter_networksetting_network.py +0 -0
  69. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0019_host_agent_version_host_docker_api_version.py +0 -0
  70. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0020_container_hostname.py +0 -0
  71. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0021_registry_and_more.py +0 -0
  72. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0022_bind_bind_netbox_docker_plugin_bind_unique_bind.py +0 -0
  73. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0023_delete_hosts.py +0 -0
  74. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0024_registry_host_alter_registry_name_and_more.py +0 -0
  75. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0025_alter_image_version.py +0 -0
  76. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0026_image_digest.py +0 -0
  77. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0027_container_restart_policy.py +0 -0
  78. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0028_mount_and_bind_read_only.py +0 -0
  79. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0029_alter_container_state.py +0 -0
  80. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0030_alter_container_containerid_alter_container_hostname_and_more.py +0 -0
  81. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0031_container_cap_add.py +0 -0
  82. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0032_device_and_more.py +0 -0
  83. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0033_host_operation.py +0 -0
  84. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0034_volume_max_size.py +0 -0
  85. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0035_container_log_driver_logdriveroption.py +0 -0
  86. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0036_alter_container_log_driver.py +0 -0
  87. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0037_alter_env_value.py +0 -0
  88. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/0038_container_cmd.py +0 -0
  89. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/1039_alter_port_public_port.py +0 -0
  90. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/1040_alter_container_log_driver.py +0 -0
  91. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/1041_sysctl.py +0 -0
  92. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/1042_registry_username_max_length.py +0 -0
  93. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/1043_container_cap_drop_container_extra_hosts_and_more.py +0 -0
  94. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/migrations/__init__.py +0 -0
  95. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/models/__init__.py +0 -0
  96. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/models/image.py +0 -0
  97. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/models/network.py +0 -0
  98. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/models/registry.py +0 -0
  99. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/models/volume.py +0 -0
  100. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/navigation.py +0 -0
  101. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/signals.py +0 -0
  102. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/templates/netbox_docker_plugin/container-exec.html +0 -0
  103. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/templates/netbox_docker_plugin/container-layout.html +0 -0
  104. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/templates/netbox_docker_plugin/container-logs.html +0 -0
  105. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/templates/netbox_docker_plugin/container.html +0 -0
  106. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/templates/netbox_docker_plugin/host-graph.html +0 -0
  107. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/templates/netbox_docker_plugin/image.html +0 -0
  108. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/templates/netbox_docker_plugin/network.html +0 -0
  109. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/templates/netbox_docker_plugin/registry.html +0 -0
  110. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/templates/netbox_docker_plugin/volume.html +0 -0
  111. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/templatetags/__init__.py +0 -0
  112. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/templatetags/host.py +0 -0
  113. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/__init__.py +0 -0
  114. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/base.py +0 -0
  115. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/container/__init__.py +0 -0
  116. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/container/test_container_actions.py +0 -0
  117. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/host/__init__.py +0 -0
  118. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/host/test_host_api.py +0 -0
  119. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/host/test_replace_password.py +0 -0
  120. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/image/__init__.py +0 -0
  121. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/image/test_force_pull_image_with_special_cf.py +0 -0
  122. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/image/test_image_api.py +0 -0
  123. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/image/test_image_views.py +0 -0
  124. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/network/__init__.py +0 -0
  125. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/network/test_network_api.py +0 -0
  126. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/network/test_network_views.py +0 -0
  127. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/registry/__init__.py +0 -0
  128. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/registry/test_registry_api.py +0 -0
  129. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/registry/test_registry_views.py +0 -0
  130. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/test_init.py +0 -0
  131. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/volume/__init__.py +0 -0
  132. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/tests/volume/test_volume_views.py +0 -0
  133. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/utilities/__init__.py +0 -0
  134. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/__init__.py +0 -0
  135. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/bind.py +0 -0
  136. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/device.py +0 -0
  137. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/env.py +0 -0
  138. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/image.py +0 -0
  139. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/label.py +0 -0
  140. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/log_driver_option.py +0 -0
  141. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/mount.py +0 -0
  142. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/network.py +0 -0
  143. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/network_setting.py +0 -0
  144. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/port.py +0 -0
  145. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/registry.py +0 -0
  146. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/sysctl.py +0 -0
  147. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin/views/volume.py +0 -0
  148. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin.egg-info/dependency_links.txt +0 -0
  149. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/netbox_docker_plugin.egg-info/top_level.txt +0 -0
  150. {netbox_docker_plugin-5.1.0 → netbox_docker_plugin-5.2.0}/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.2.0
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.2.0"
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>"
@@ -5,6 +5,7 @@
5
5
  from rest_framework import serializers
6
6
  from utilities.query import dict_to_filter_params
7
7
  from users.models import Token
8
+ from virtualization.api.serializers import VirtualMachineSerializer
8
9
  from netbox.api.serializers import NetBoxModelSerializer, WritableNestedSerializer
9
10
  from ..models.host import Host
10
11
  from ..models.image import Image
@@ -693,6 +694,7 @@ class HostSerializer(NetBoxModelSerializer):
693
694
  containers = NestedContainerSerializer(many=True, read_only=True)
694
695
  registries = NestedRegistrySerializer(many=True, read_only=True)
695
696
  token = NestedTokenSerializer(read_only=True)
697
+ virtual_machine = VirtualMachineSerializer(required=False)
696
698
 
697
699
  class Meta:
698
700
  """Host Serializer Meta class"""
@@ -706,6 +708,7 @@ class HostSerializer(NetBoxModelSerializer):
706
708
  "name",
707
709
  "state",
708
710
  "token",
711
+ "virtual_machine",
709
712
  "netbox_base_url",
710
713
  "agent_version",
711
714
  "docker_api_version",
@@ -39,7 +39,13 @@ class HostViewSet(NetBoxModelViewSet):
39
39
  """Host view set class"""
40
40
 
41
41
  queryset = Host.objects.prefetch_related(
42
- "images", "volumes", "networks", "containers", "registries", "tags"
42
+ "images",
43
+ "volumes",
44
+ "networks",
45
+ "containers",
46
+ "registries",
47
+ "virtual_machine",
48
+ "tags",
43
49
  )
44
50
  filterset_class = filtersets.HostFilterSet
45
51
  serializer_class = HostSerializer
@@ -108,7 +114,7 @@ class ImageViewSet(NetBoxModelViewSet):
108
114
  url,
109
115
  timeout=10,
110
116
  data=json.dumps({"data": data}, cls=DjangoJSONEncoder),
111
- headers={"Content-Type": "application/json"}
117
+ headers={"Content-Type": "application/json"},
112
118
  )
113
119
  resp.raise_for_status()
114
120
 
@@ -38,6 +38,7 @@ class HostFilterSet(NetBoxModelFilterSet):
38
38
  "state",
39
39
  "agent_version",
40
40
  "docker_api_version",
41
+ "virtual_machine",
41
42
  )
42
43
 
43
44
  # pylint: disable=W0613
@@ -2,7 +2,8 @@
2
2
 
3
3
  from django import forms
4
4
  from utilities.forms.rendering import FieldSet
5
- from utilities.forms.fields import TagFilterField
5
+ from utilities.forms.fields import TagFilterField, DynamicModelChoiceField
6
+ from virtualization.models import VirtualMachine
6
7
  from netbox.forms import (
7
8
  NetBoxModelForm,
8
9
  NetBoxModelImportForm,
@@ -12,9 +13,43 @@ from netbox.forms import (
12
13
  from ..models.host import Host, HostStateChoices
13
14
 
14
15
 
16
+ class HostAddForm(NetBoxModelForm):
17
+ """Host form definition class"""
18
+
19
+ virtual_machine = DynamicModelChoiceField(
20
+ queryset=VirtualMachine.objects.all(),
21
+ selector=True,
22
+ required=False,
23
+ label="Virtual Machine",
24
+ )
25
+
26
+ class Meta:
27
+ """Host form definition Meta class"""
28
+
29
+ model = Host
30
+ fields = (
31
+ "name",
32
+ "endpoint",
33
+ "virtual_machine",
34
+ )
35
+ help_texts = {"name": "Unique Name", "endpoint": "Docker instance endpoint"}
36
+ labels = {"name": "Name", "endpoint": "Endpoint"}
37
+
38
+ def __init__(self, *args, **kwargs):
39
+ super().__init__(*args, **kwargs)
40
+ self.fields.pop("tags", None)
41
+
42
+
15
43
  class HostForm(NetBoxModelForm):
16
44
  """Host form definition class"""
17
45
 
46
+ virtual_machine = DynamicModelChoiceField(
47
+ queryset=VirtualMachine.objects.all(),
48
+ selector=True,
49
+ required=False,
50
+ label="Virtual Machine",
51
+ )
52
+
18
53
  class Meta:
19
54
  """Host form definition Meta class"""
20
55
 
@@ -22,6 +57,7 @@ class HostForm(NetBoxModelForm):
22
57
  fields = (
23
58
  "name",
24
59
  "endpoint",
60
+ "virtual_machine",
25
61
  "tags",
26
62
  )
27
63
  help_texts = {"name": "Unique Name", "endpoint": "Docker instance endpoint"}
@@ -0,0 +1,29 @@
1
+ # pylint: disable=C0103
2
+ """Migration file"""
3
+
4
+ import django.db.models.deletion
5
+ from django.db import migrations, models
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+ """Migration file"""
10
+
11
+ dependencies = [
12
+ (
13
+ "netbox_docker_plugin",
14
+ "1043_container_cap_drop_container_extra_hosts_and_more",
15
+ ),
16
+ ]
17
+
18
+ operations = [
19
+ migrations.AddField(
20
+ model_name="host",
21
+ name="virtual_machine",
22
+ field=models.OneToOneField(
23
+ blank=True,
24
+ null=True,
25
+ on_delete=django.db.models.deletion.SET_NULL,
26
+ to="virtualization.virtualmachine",
27
+ ),
28
+ ),
29
+ ]
@@ -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
 
@@ -314,6 +328,7 @@ class Container(NetBoxModel):
314
328
  return reverse("plugins:netbox_docker_plugin:container", args=[self.pk])
315
329
 
316
330
  def clean(self):
331
+ """Validate that the image belongs to the same host and has been pulled."""
317
332
  super().clean()
318
333
 
319
334
  if self.host != self.image.host:
@@ -321,6 +336,11 @@ class Container(NetBoxModel):
321
336
  {"image": f"Image {self.image} does not belong to host {self.host}."}
322
337
  )
323
338
 
339
+ if not self.image.ImageID:
340
+ raise ValidationError(
341
+ {"image": f"Image {self.image} has no ID yet. Pull or refresh it first."}
342
+ )
343
+
324
344
 
325
345
  class Port(models.Model):
326
346
  """Container definition class"""
@@ -9,6 +9,7 @@ from django.core.validators import (
9
9
  )
10
10
  from utilities.choices import ChoiceSet
11
11
  from users.models import Token
12
+ from virtualization.models import VirtualMachine
12
13
  from netbox.models import NetBoxModel
13
14
 
14
15
 
@@ -64,6 +65,12 @@ class Host(NetBoxModel):
64
65
  default=HostStateChoices.STATE_CREATED,
65
66
  )
66
67
  token = models.ForeignKey(Token, on_delete=models.SET_NULL, null=True, blank=True)
68
+ virtual_machine = models.OneToOneField(
69
+ VirtualMachine,
70
+ on_delete=models.SET_NULL,
71
+ null=True,
72
+ blank=True,
73
+ )
67
74
  netbox_base_url = models.CharField(
68
75
  max_length=1024,
69
76
  validators=[URLValidator()],
@@ -26,6 +26,7 @@ class HostTable(NetBoxTable):
26
26
  """Host Table definition class"""
27
27
 
28
28
  name = tables.Column(linkify=True)
29
+ virtual_machine = tables.Column(linkify=True, verbose_name="Virtual Machine")
29
30
  image_count = columns.LinkedCountColumn(
30
31
  viewname="plugins:netbox_docker_plugin:image_list",
31
32
  url_params={"host_id": "pk"},
@@ -62,6 +63,7 @@ class HostTable(NetBoxTable):
62
63
  "name",
63
64
  "endpoint",
64
65
  "state",
66
+ "virtual_machine",
65
67
  "agent_version",
66
68
  "docker_api_version",
67
69
  "image_count",
@@ -0,0 +1,23 @@
1
+ """Template modifications definitions"""
2
+
3
+ # pylint: disable=W0223
4
+
5
+ from netbox.plugins import PluginTemplateExtension
6
+ from .models import Host
7
+
8
+
9
+ class VirtualMachineHostTable(PluginTemplateExtension):
10
+ """Virtual machine object template"""
11
+
12
+ models = ["virtualization.virtualmachine"]
13
+
14
+ def right_page(self):
15
+ return self.render(
16
+ "netbox_docker_plugin/virtual_machine_host_table.html",
17
+ extra_context={
18
+ "Host": Host.objects.filter(virtual_machine=self.context["object"])
19
+ },
20
+ )
21
+
22
+
23
+ template_extensions = [VirtualMachineHostTable]
@@ -27,6 +27,17 @@
27
27
  <th scope="row">Endpoint</th>
28
28
  <td>{{ object.endpoint|remove_password }}</td>
29
29
  </tr>
30
+ <tr>
31
+ <th scope="row">Virtual Machine</th>
32
+ <td>
33
+ {% if object.virtual_machine %}
34
+ <a href="{% url 'virtualization:virtualmachine' pk=object.virtual_machine.pk %}">
35
+ {{ object.virtual_machine|placeholder }}</a>
36
+ {% else %}
37
+ {{ object.virtual_machine|placeholder }}</a>
38
+ {% endif %}
39
+ </td>
40
+ </tr>
30
41
  <tr>
31
42
  <th scope="row">State</th>
32
43
  <td>{{ object.get_state_display }}</td>
@@ -0,0 +1,4 @@
1
+ <div class="card">
2
+ <h2 class="card-header">Docker Host</h2>
3
+ {% htmx_table 'plugins:netbox_docker_plugin:host_list' virtual_machine=object.pk %}
4
+ </div>
@@ -70,8 +70,18 @@ class ContainerApiTestCase(
70
70
  host=host2, name="registry2", serveraddress="http://localhost:8082"
71
71
  )
72
72
 
73
- image1 = Image.objects.create(host=host1, name="image1", registry=registry1)
74
- image2 = Image.objects.create(host=host2, name="image2", registry=registry2)
73
+ image1 = Image.objects.create(
74
+ host=host1,
75
+ name="image1",
76
+ registry=registry1,
77
+ ImageID="sha256:abc123",
78
+ )
79
+ image2 = Image.objects.create(
80
+ host=host2,
81
+ name="image2",
82
+ registry=registry2,
83
+ ImageID="sha256:abc456",
84
+ )
75
85
 
76
86
  network1 = Network.objects.create(host=host1, name="network1")
77
87
  network2 = Network.objects.create(host=host2, name="network2")
@@ -244,6 +254,7 @@ class ContainerApiTestCase(
244
254
  host=host3,
245
255
  name="image3",
246
256
  registry=registry3,
257
+ ImageID="sha256:abc789",
247
258
  )
248
259
  container11 = Container.objects.create(
249
260
  host=host3,
@@ -330,8 +341,18 @@ class ContainerApiTestCase(
330
341
  host=host2, name="registry5", serveraddress="http://localhost:8082"
331
342
  )
332
343
 
333
- image1 = Image.objects.create(host=host1, name="image", registry=registry1)
334
- image2 = Image.objects.create(host=host2, name="image", registry=registry2)
344
+ image1 = Image.objects.create(
345
+ host=host1,
346
+ name="image",
347
+ registry=registry1,
348
+ ImageID="sha256:abc101112",
349
+ )
350
+ image2 = Image.objects.create(
351
+ host=host2,
352
+ name="image",
353
+ registry=registry2,
354
+ ImageID="sha256:abc131415",
355
+ )
335
356
 
336
357
  container = Container.objects.create(host=host1, image=image1, name="container")
337
358
 
@@ -28,7 +28,12 @@ class ContainerApiExecTestCase(BaseAPITestCase):
28
28
  host=host1, name="registry1", serveraddress="http://localhost:8080"
29
29
  )
30
30
 
31
- image1 = Image.objects.create(host=host1, name="image1", registry=registry1)
31
+ image1 = Image.objects.create(
32
+ host=host1,
33
+ name="image1",
34
+ registry=registry1,
35
+ ImageID="sha256:abc123",
36
+ )
32
37
 
33
38
  container = Container.objects.create(
34
39
  host=host1,
@@ -86,11 +91,11 @@ class ContainerApiExecTestCase(BaseAPITestCase):
86
91
  m.put(
87
92
  "http://localhost:8080/api/engine/containers/1234/exec",
88
93
  text="Error",
89
- status_code= 500
94
+ status_code=500,
90
95
  )
91
96
 
92
97
  response = self.client.post(
93
98
  self.endpoint, **self.header, data={"cmd": ["ls"]}, format="json"
94
99
  )
95
100
  self.assertHttpStatus(response, status.HTTP_502_BAD_GATEWAY)
96
- self.assertEqual(response.data, 'Error')
101
+ self.assertEqual(response.data, "Error")
@@ -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
+ )
@@ -257,8 +257,12 @@ class ContainerViewsTestCase(BaseModelViewTestCase, ModelViewTestCase):
257
257
  host=host2, name="registry2", serveraddress="http://localhost:8082"
258
258
  )
259
259
 
260
- image1 = Image.objects.create(host=host1, name="image1", registry=registry1)
261
- image2 = Image.objects.create(host=host2, name="image2", registry=registry2)
260
+ image1 = Image.objects.create(
261
+ host=host1, name="image1", registry=registry1, ImageID="sha256:abc123"
262
+ )
263
+ image2 = Image.objects.create(
264
+ host=host2, name="image2", registry=registry2, ImageID="sha256:abc456"
265
+ )
262
266
 
263
267
  Container.objects.create(
264
268
  host=host1,
@@ -39,6 +39,36 @@ class ContainerValidationTestCase(TestCase):
39
39
 
40
40
  self.assertTrue(isinstance(container.id, int))
41
41
 
42
+ def test_that_container_image_must_have_an_id(self):
43
+ """Test that the image must have been pulled (non-empty ImageID)"""
44
+
45
+ with self.assertRaises(ValidationError) as cm:
46
+ container = Container(
47
+ host=self.objects["host1"],
48
+ image=self.objects["image1"],
49
+ name="container_no_image_id",
50
+ operation="none",
51
+ state="created",
52
+ )
53
+ container.clean()
54
+
55
+ self.assertEqual(
56
+ cm.exception.message_dict["image"],
57
+ ["Image image1:latest has no ID yet. Pull or refresh it first."],
58
+ )
59
+
60
+ def test_that_container_image_with_id_passes_validation(self):
61
+ """Test that an image with a non-empty ImageID passes validation"""
62
+
63
+ container = Container(
64
+ host=self.objects["host1"],
65
+ image=self.objects["image1_pulled"],
66
+ name="container_with_image_id",
67
+ operation="none",
68
+ state="created",
69
+ )
70
+ container.clean() # must not raise
71
+
42
72
  def test_that_container_image_must_be_on_the_same_host(self):
43
73
  """Test that Container image must be on the same host"""
44
74
 
@@ -138,6 +168,12 @@ class ContainerValidationTestCase(TestCase):
138
168
  cls.objects["image1"] = Image.objects.create(
139
169
  host=cls.objects["host1"], name="image1", registry=cls.objects["registry1"]
140
170
  )
171
+ cls.objects["image1_pulled"] = Image.objects.create(
172
+ host=cls.objects["host1"],
173
+ name="image1_pulled",
174
+ registry=cls.objects["registry1"],
175
+ ImageID="sha256:abc123",
176
+ )
141
177
  cls.objects["image2"] = Image.objects.create(
142
178
  host=cls.objects["host2"], name="image2", registry=cls.objects["registry2"]
143
179
  )
@@ -28,8 +28,12 @@ class ContainerViewsTestCase(
28
28
  host=host2, name="registry2", serveraddress="http://localhost:8082"
29
29
  )
30
30
 
31
- image1 = Image.objects.create(host=host1, name="image1", registry=registry1)
32
- image2 = Image.objects.create(host=host2, name="image2", registry=registry2)
31
+ image1 = Image.objects.create(
32
+ host=host1, name="image1", registry=registry1, ImageID="sha256:abc123"
33
+ )
34
+ image2 = Image.objects.create(
35
+ host=host2, name="image2", registry=registry2, ImageID="sha256:abc456"
36
+ )
33
37
 
34
38
  container1 = Container.objects.create(
35
39
  host=host1,
@@ -26,6 +26,7 @@ class HostViewsTestCase(BaseModelViewTestCase, ViewTestCases.PrimaryObjectViewTe
26
26
  "host7,http://localhost:8084",
27
27
  )
28
28
  bulk_edit_data = {"endpoint": "http://localhost:8083"}
29
+ validation_excluded_fields = ["tags"]
29
30
 
30
31
  def setUp(self):
31
32
  super().setUp()
@@ -91,8 +92,7 @@ class HostViewsTestCase(BaseModelViewTestCase, ViewTestCases.PrimaryObjectViewTe
91
92
  """Test the host error state"""
92
93
 
93
94
  self.assertEqual(
94
- self.objects["host_error_state"].state,
95
- HostStateChoices.STATE_ERROR
95
+ self.objects["host_error_state"].state, HostStateChoices.STATE_ERROR
96
96
  )
97
97
 
98
98
  @classmethod