netbox-docker-plugin 1.5.2__tar.gz → 1.6.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 (114) hide show
  1. {netbox_docker_plugin-1.5.2/netbox_docker_plugin.egg-info → netbox_docker_plugin-1.6.1}/PKG-INFO +1 -1
  2. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/__init__.py +1 -1
  3. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/api/serializers.py +19 -0
  4. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/filtersets.py +1 -1
  5. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/forms/container.py +24 -6
  6. netbox_docker_plugin-1.6.1/netbox_docker_plugin/migrations/0026_image_digest.py +29 -0
  7. netbox_docker_plugin-1.6.1/netbox_docker_plugin/migrations/0027_container_restart_policy.py +20 -0
  8. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/models/container.py +20 -0
  9. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/models/image.py +9 -0
  10. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tables.py +1 -0
  11. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/templates/netbox_docker_plugin/container.html +4 -0
  12. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/templates/netbox_docker_plugin/image.html +10 -0
  13. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/container/test_container_api.py +1 -0
  14. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/container/test_container_views.py +9 -5
  15. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/image/test_image_api.py +1 -0
  16. netbox_docker_plugin-1.6.1/netbox_docker_plugin/tests/volume/test_volume_api.py +122 -0
  17. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1/netbox_docker_plugin.egg-info}/PKG-INFO +1 -1
  18. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin.egg-info/SOURCES.txt +2 -0
  19. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/pyproject.toml +1 -1
  20. netbox_docker_plugin-1.5.2/netbox_docker_plugin/tests/volume/test_volume_api.py +0 -44
  21. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/LICENSE +0 -0
  22. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/MANIFEST.in +0 -0
  23. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/README.md +0 -0
  24. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/api/__init__.py +0 -0
  25. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/api/urls.py +0 -0
  26. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/api/views.py +0 -0
  27. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/forms/__init__.py +0 -0
  28. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/forms/bind.py +0 -0
  29. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/forms/env.py +0 -0
  30. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/forms/host.py +0 -0
  31. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/forms/image.py +0 -0
  32. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/forms/label.py +0 -0
  33. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/forms/mount.py +0 -0
  34. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/forms/network.py +0 -0
  35. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/forms/network_setting.py +0 -0
  36. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/forms/port.py +0 -0
  37. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/forms/registry.py +0 -0
  38. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/forms/volume.py +0 -0
  39. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0001_initial.py +0 -0
  40. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0002_image.py +0 -0
  41. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0003_image_size.py +0 -0
  42. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0004_volume.py +0 -0
  43. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0005_network.py +0 -0
  44. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0006_container_port_mount_label_env_and_more.py +0 -0
  45. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0007_remove_container_netbox_docker_plugin_container_unique_name_host__and_more.py +0 -0
  46. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0008_alter_network_unique_together_network_networkid_and_more.py +0 -0
  47. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0009_remove_container_network_networksettings_and_more.py +0 -0
  48. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0010_container_containerid_and_more.py +0 -0
  49. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0011_host_token.py +0 -0
  50. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0012_host_state.py +0 -0
  51. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0013_host_netbox_url.py +0 -0
  52. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0014_container_operation.py +0 -0
  53. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0015_remove_mount_netbox_docker_plugin_mount_unique_volume_and_more.py +0 -0
  54. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0016_alter_env_value.py +0 -0
  55. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0017_network_state.py +0 -0
  56. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0018_alter_mount_volume_alter_networksetting_network.py +0 -0
  57. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0019_host_agent_version_host_docker_api_version.py +0 -0
  58. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0020_container_hostname.py +0 -0
  59. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0021_registry_and_more.py +0 -0
  60. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0022_bind_bind_netbox_docker_plugin_bind_unique_bind.py +0 -0
  61. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0023_delete_hosts.py +0 -0
  62. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0024_registry_host_alter_registry_name_and_more.py +0 -0
  63. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/0025_alter_image_version.py +0 -0
  64. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/migrations/__init__.py +0 -0
  65. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/models/__init__.py +0 -0
  66. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/models/host.py +0 -0
  67. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/models/network.py +0 -0
  68. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/models/registry.py +0 -0
  69. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/models/volume.py +0 -0
  70. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/navigation.py +0 -0
  71. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/templates/netbox_docker_plugin/host.html +0 -0
  72. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/templates/netbox_docker_plugin/network.html +0 -0
  73. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/templates/netbox_docker_plugin/registry.html +0 -0
  74. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/templates/netbox_docker_plugin/volume.html +0 -0
  75. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/templatetags/__init__.py +0 -0
  76. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/templatetags/host.py +0 -0
  77. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/__init__.py +0 -0
  78. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/base.py +0 -0
  79. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/container/__init__.py +0 -0
  80. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/container/test_container_operation_view.py +0 -0
  81. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/container/test_container_validation.py +0 -0
  82. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/host/__init__.py +0 -0
  83. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/host/test_host_api.py +0 -0
  84. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/host/test_host_views.py +0 -0
  85. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/host/test_replace_password.py +0 -0
  86. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/image/__init__.py +0 -0
  87. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/image/test_image_views.py +0 -0
  88. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/network/__init__.py +0 -0
  89. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/network/test_network_api.py +0 -0
  90. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/network/test_network_views.py +0 -0
  91. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/registry/__init__.py +0 -0
  92. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/registry/test_registry_api.py +0 -0
  93. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/registry/test_registry_views.py +0 -0
  94. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/test_init.py +0 -0
  95. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/volume/__init__.py +0 -0
  96. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/tests/volume/test_volume_views.py +0 -0
  97. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/urls.py +0 -0
  98. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/utilities/__init__.py +0 -0
  99. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/views/__init__.py +0 -0
  100. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/views/bind.py +0 -0
  101. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/views/container.py +0 -0
  102. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/views/env.py +0 -0
  103. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/views/host.py +0 -0
  104. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/views/image.py +0 -0
  105. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/views/label.py +0 -0
  106. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/views/mount.py +0 -0
  107. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/views/network.py +0 -0
  108. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/views/network_setting.py +0 -0
  109. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/views/port.py +0 -0
  110. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/views/registry.py +0 -0
  111. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin/views/volume.py +0 -0
  112. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin.egg-info/dependency_links.txt +0 -0
  113. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/netbox_docker_plugin.egg-info/top_level.txt +0 -0
  114. {netbox_docker_plugin-1.5.2 → netbox_docker_plugin-1.6.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: netbox-docker-plugin
3
- Version: 1.5.2
3
+ Version: 1.6.1
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.5.2"
13
+ version = "1.6.1"
14
14
  base_url = "docker"
15
15
  author= "Vincent Simonin"
16
16
  author_email= "vincent@saashup.com"
@@ -3,6 +3,7 @@
3
3
  # pylint: disable=E1101
4
4
 
5
5
  from rest_framework import serializers
6
+ from utilities.utils import dict_to_filter_params
6
7
  from users.api.nested_serializers import NestedTokenSerializer
7
8
  from netbox.api.serializers import NetBoxModelSerializer, WritableNestedSerializer
8
9
  from ..models.host import Host
@@ -63,6 +64,7 @@ class NestedImageSerializer(WritableNestedSerializer):
63
64
  "version",
64
65
  "size",
65
66
  "ImageID",
67
+ "Digest",
66
68
  )
67
69
 
68
70
 
@@ -85,6 +87,20 @@ class NestedVolumeSerializer(WritableNestedSerializer):
85
87
  "driver",
86
88
  )
87
89
 
90
+ def to_internal_value(self, data):
91
+ if data is None:
92
+ return None
93
+
94
+ if isinstance(data, dict):
95
+ params = dict_to_filter_params(data)
96
+ if Volume.objects.filter(**params).count() == 0:
97
+ host = Host.objects.get(pk=params["host"])
98
+ volume = Volume(host= host, name= params["name"])
99
+ volume.save()
100
+ return volume
101
+
102
+ return super().to_internal_value(data)
103
+
88
104
 
89
105
  class NestedNetworkSerializer(WritableNestedSerializer):
90
106
  """Nested Network Serializer class"""
@@ -126,6 +142,7 @@ class NestedContainerSerializer(WritableNestedSerializer):
126
142
  "ContainerID",
127
143
  "state",
128
144
  "status",
145
+ "restart_policy",
129
146
  "operation",
130
147
  "hostname",
131
148
  )
@@ -203,6 +220,7 @@ class ImageSerializer(NetBoxModelSerializer):
203
220
  "registry",
204
221
  "size",
205
222
  "ImageID",
223
+ "Digest",
206
224
  "custom_fields",
207
225
  "created",
208
226
  "last_updated",
@@ -379,6 +397,7 @@ class ContainerSerializer(NetBoxModelSerializer):
379
397
  "status",
380
398
  "ContainerID",
381
399
  "hostname",
400
+ "restart_policy",
382
401
  "ports",
383
402
  "env",
384
403
  "labels",
@@ -165,7 +165,7 @@ class ContainerFilterSet(NetBoxModelFilterSet):
165
165
  """Container filterset definition meta class"""
166
166
 
167
167
  model = Container
168
- fields = ("id", "name", "state", "hostname")
168
+ fields = ("id", "name", "state", "hostname", "restart_policy")
169
169
 
170
170
  # pylint: disable=W0613
171
171
  def search(self, queryset, name, value):
@@ -14,7 +14,11 @@ from netbox.forms import (
14
14
  )
15
15
  from ..models.volume import Volume
16
16
  from ..models.host import Host
17
- from ..models.container import Container, ContainerStateChoices
17
+ from ..models.container import (
18
+ Container,
19
+ ContainerStateChoices,
20
+ ContainerRestartPolicyChoices,
21
+ )
18
22
  from ..models.image import Image
19
23
 
20
24
 
@@ -41,6 +45,7 @@ class ContainerForm(NetBoxModelForm):
41
45
  "name",
42
46
  "hostname",
43
47
  "state",
48
+ "restart_policy",
44
49
  "tags",
45
50
  )
46
51
  labels = {
@@ -49,6 +54,7 @@ class ContainerForm(NetBoxModelForm):
49
54
  "image": "Image",
50
55
  "hostname": "Hostname",
51
56
  "state": "State",
57
+ "restart_policy": "Restart Policy",
52
58
  }
53
59
 
54
60
 
@@ -76,6 +82,9 @@ class ContainerFilterForm(NetBoxModelFilterSetForm):
76
82
  state = forms.ChoiceField(
77
83
  label="State", choices=ContainerStateChoices, required=False
78
84
  )
85
+ restart_policy = forms.ChoiceField(
86
+ label="Restart Policy", choices=ContainerRestartPolicyChoices, required=False
87
+ )
79
88
  tag = TagFilterField(model)
80
89
 
81
90
 
@@ -87,7 +96,14 @@ class ContainerImportForm(NetBoxModelImportForm):
87
96
  choices=ContainerStateChoices,
88
97
  required=False,
89
98
  help_text="Container State. Can be `created`, `restarting`, "
90
- + "`running`, `paused`, `exited`or `dead`.",
99
+ + "`running`, `paused`, `exited` or `dead`.",
100
+ )
101
+ restart_policy = forms.ChoiceField(
102
+ label="Restart Policy",
103
+ choices=ContainerRestartPolicyChoices,
104
+ required=False,
105
+ help_text="Container restart policy. Can be `no`, `on-failure`, "
106
+ + "`always`, `unless-stopped`.",
91
107
  )
92
108
 
93
109
  class Meta:
@@ -105,9 +121,6 @@ class ContainerImportForm(NetBoxModelImportForm):
105
121
  "name": "Unique container name",
106
122
  "host": "Host identifier",
107
123
  "image": "Image identifier",
108
- "state": "Container State. Can be `created`, `restarting`, "
109
- + "`running`, `paused`, `exited`or `dead`.",
110
- "hostname": "Container hostname"
111
124
  }
112
125
 
113
126
 
@@ -119,12 +132,17 @@ class ContainerBulkEditForm(NetBoxModelBulkEditForm):
119
132
  choices=ContainerStateChoices,
120
133
  required=True,
121
134
  )
135
+ restart_policy = forms.ChoiceField(
136
+ label="Restart Policy",
137
+ choices=ContainerRestartPolicyChoices,
138
+ required=True,
139
+ )
122
140
  hostname = forms.CharField(
123
141
  label="Hostname", max_length=256, min_length=1, required=False
124
142
  )
125
143
 
126
144
  model = Container
127
- fieldsets = (("General", ("state", "hostname")),)
145
+ fieldsets = (("General", ("state", "restart_policy", "hostname")),)
128
146
 
129
147
 
130
148
  class ContainerOperationForm(NetBoxModelForm):
@@ -0,0 +1,29 @@
1
+ # pylint: disable=C0103
2
+ """Migration file"""
3
+
4
+ import django.core.validators
5
+ from django.db import migrations, models
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+ """Migration file"""
10
+
11
+ dependencies = [
12
+ ("netbox_docker_plugin", "0025_alter_image_version"),
13
+ ]
14
+
15
+ operations = [
16
+ migrations.AddField(
17
+ model_name="image",
18
+ name="Digest",
19
+ field=models.CharField(
20
+ blank=True,
21
+ max_length=512,
22
+ null=True,
23
+ validators=[
24
+ django.core.validators.MinLengthValidator(limit_value=1),
25
+ django.core.validators.MaxLengthValidator(limit_value=512),
26
+ ],
27
+ ),
28
+ ),
29
+ ]
@@ -0,0 +1,20 @@
1
+ # pylint: disable=C0103
2
+ """Migration file"""
3
+
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ """Migration file"""
9
+
10
+ dependencies = [
11
+ ("netbox_docker_plugin", "0026_image_digest"),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.AddField(
16
+ model_name="container",
17
+ name="restart_policy",
18
+ field=models.CharField(default="no", max_length=32),
19
+ ),
20
+ ]
@@ -56,6 +56,21 @@ class ContainerOperationChoices(ChoiceSet):
56
56
  ]
57
57
 
58
58
 
59
+ class ContainerRestartPolicyChoices(ChoiceSet):
60
+ """Container restart policy choices definition class"""
61
+
62
+ key = "Container.restart_policy"
63
+
64
+ DEFAULT_VALUE = "no"
65
+
66
+ CHOICES = [
67
+ ("no", "no", "dark"),
68
+ ("on-failure", "on-failure", "blue"),
69
+ ("always", "always", "blue"),
70
+ ("unless-stopped", "unless-stopped", "blue"),
71
+ ]
72
+
73
+
59
74
  class PortTypeChoices(ChoiceSet):
60
75
  """Port type choices definition class"""
61
76
 
@@ -112,6 +127,11 @@ class Container(NetBoxModel):
112
127
  blank=True,
113
128
  null=True,
114
129
  )
130
+ restart_policy = models.CharField(
131
+ max_length=32,
132
+ choices=ContainerRestartPolicyChoices,
133
+ default=ContainerRestartPolicyChoices.DEFAULT_VALUE,
134
+ )
115
135
 
116
136
  class Meta:
117
137
  """Image Model Meta Class"""
@@ -53,6 +53,15 @@ class Image(NetBoxModel):
53
53
  blank=True,
54
54
  null=True,
55
55
  )
56
+ Digest = models.CharField(
57
+ max_length=512,
58
+ validators=[
59
+ MinLengthValidator(limit_value=1),
60
+ MaxLengthValidator(limit_value=512),
61
+ ],
62
+ blank=True,
63
+ null=True,
64
+ )
56
65
 
57
66
  class Meta:
58
67
  """Image Model Meta Class"""
@@ -255,6 +255,7 @@ class ContainerTable(NetBoxTable):
255
255
  "status",
256
256
  "ContainerID",
257
257
  "hostname",
258
+ "restart_policy",
258
259
  "port_count",
259
260
  "mount_count",
260
261
  "bind_count",
@@ -67,6 +67,10 @@
67
67
  <th scope="row">State</th>
68
68
  <td>{{ object.get_state_display }}</td>
69
69
  </tr>
70
+ <tr>
71
+ <th scope="row">Restart Policy</th>
72
+ <td>{{ object.get_restart_policy_display }}</td>
73
+ </tr>
70
74
  <tr>
71
75
  <th scope="row">Status</th>
72
76
  <td>{{ object.status|placeholder }}</td>
@@ -29,6 +29,16 @@
29
29
  <th scope="row">ImageID</th>
30
30
  <td>{{ object.ImageID|placeholder }}</td>
31
31
  </tr>
32
+ <tr>
33
+ <th scope="row">Digest</th>
34
+ <td>
35
+ {% if object.Digest is None %}
36
+ {{ object.Digest|placeholder }}
37
+ {% else %}
38
+ {{ object.Digest|truncatechars:32 }}
39
+ {% endif %}
40
+ </td>
41
+ </tr>
32
42
  </table>
33
43
  </div>
34
44
  </div>
@@ -27,6 +27,7 @@ class ContainerApiTestCase(
27
27
  "id",
28
28
  "name",
29
29
  "operation",
30
+ "restart_policy",
30
31
  "state",
31
32
  "status",
32
33
  "url",
@@ -31,7 +31,7 @@ class ContainerViewsTestCase(
31
31
  image2 = Image.objects.create(host=host2, name="image2", registry=registry2)
32
32
 
33
33
  container1 = Container.objects.create(
34
- host=host1, image=image1, name="container1"
34
+ host=host1, image=image1, name="container1", restart_policy="always"
35
35
  )
36
36
  container2 = Container.objects.create(
37
37
  host=host1, image=image1, name="container2"
@@ -44,6 +44,7 @@ class ContainerViewsTestCase(
44
44
  "host": host1.pk,
45
45
  "image": image1.pk,
46
46
  "state": "created",
47
+ "restart_policy": "unless-stopped",
47
48
  }
48
49
 
49
50
  cls.csv_data = (
@@ -52,10 +53,13 @@ class ContainerViewsTestCase(
52
53
  f"container7,{host2.pk},{image2.pk},container7",
53
54
  )
54
55
 
55
- cls.bulk_edit_data = {"state": "running"}
56
+ cls.bulk_edit_data = {
57
+ "state": "running",
58
+ "restart_policy": "always",
59
+ }
56
60
 
57
61
  cls.csv_update_data = (
58
- "id,name,host,image,state,hostname",
59
- f"{container1.pk},container1,{host1.pk},{image1.pk},paused,",
60
- f"{container2.pk},container2,{host1.pk},{image1.pk},running,container2",
62
+ "id,name,host,image,state,hostname,restart_policy",
63
+ f"{container1.pk},container1,{host1.pk},{image1.pk},paused,,on-failure",
64
+ f"{container2.pk},container2,{host1.pk},{image1.pk},running,container2,unless-stopped",
61
65
  )
@@ -19,6 +19,7 @@ class ImageApiTestCase(
19
19
 
20
20
  model = Image
21
21
  brief_fields = [
22
+ "Digest",
22
23
  "ImageID",
23
24
  "display",
24
25
  "id",
@@ -0,0 +1,122 @@
1
+ """Volume Test Case"""
2
+
3
+ from django.urls import reverse
4
+ from django.contrib.contenttypes.models import ContentType
5
+ from rest_framework import status
6
+ from users.models import ObjectPermission
7
+ from utilities.testing import APIViewTestCases
8
+ from netbox_docker_plugin.models.host import Host
9
+ from netbox_docker_plugin.models.volume import Volume
10
+ from netbox_docker_plugin.models.image import Image
11
+ from netbox_docker_plugin.models.registry import Registry
12
+ from netbox_docker_plugin.models.container import Container, Mount
13
+ from netbox_docker_plugin.tests.base import BaseAPITestCase
14
+
15
+
16
+ class VolumeApiTestCase(
17
+ BaseAPITestCase,
18
+ APIViewTestCases.GetObjectViewTestCase,
19
+ APIViewTestCases.ListObjectsViewTestCase,
20
+ APIViewTestCases.CreateObjectViewTestCase,
21
+ APIViewTestCases.UpdateObjectViewTestCase,
22
+ APIViewTestCases.DeleteObjectViewTestCase,
23
+ ):
24
+ """Volume Test Case Class"""
25
+
26
+ model = Volume
27
+ brief_fields = ["display", "driver", "id", "name", "url"]
28
+
29
+ @classmethod
30
+ def setUpTestData(cls) -> None:
31
+ host1 = Host.objects.create(endpoint="http://localhost:8080", name="host1")
32
+ host2 = Host.objects.create(endpoint="http://localhost:8080", name="host2")
33
+
34
+ Volume.objects.create(host=host1, name="volume1")
35
+ Volume.objects.create(host=host1, name="volume2")
36
+ Volume.objects.create(host=host2, name="volume3")
37
+
38
+ cls.create_data = [
39
+ {
40
+ "host": host1.pk,
41
+ "name": "volume4",
42
+ },
43
+ {
44
+ "host": host1.pk,
45
+ "name": "volume5",
46
+ },
47
+ {
48
+ "host": host2.pk,
49
+ "name": "volume6",
50
+ },
51
+ ]
52
+
53
+ def test_that_embedded_anonymous_volume_is_created(self):
54
+ """Test that embedded anonymous Volume is created on Container update"""
55
+
56
+ # Assign model-level permission
57
+ obj_perm = ObjectPermission(
58
+ name="Test permission", actions=["add", "change", "view"]
59
+ )
60
+ obj_perm.save()
61
+ # pylint: disable=E1101
62
+ obj_perm.users.add(self.user)
63
+ # pylint: disable=E1101
64
+ obj_perm.object_types.add(ContentType.objects.get_for_model(self.model))
65
+ obj_perm.object_types.add(ContentType.objects.get_for_model(Container))
66
+ obj_perm.object_types.add(ContentType.objects.get_for_model(Mount))
67
+ obj_perm.object_types.add(ContentType.objects.get_for_model(Image))
68
+
69
+ host = Host.objects.create(endpoint="http://localhost:8088", name="host8")
70
+
71
+ registry = Registry.objects.create(
72
+ host=host, name="registry8", serveraddress="http://localhost:8089"
73
+ )
74
+
75
+ image = Image.objects.create(host=host, name="image8", registry=registry)
76
+
77
+ container = Container.objects.create(host=host, image=image, name="container8")
78
+
79
+ response = self.client.patch(
80
+ reverse(f"plugins-api:{self._get_view_namespace()}:container-list"),
81
+ # pylint: disable=C0301
82
+ [
83
+ {
84
+ "id": container.pk,
85
+ "host": host.pk,
86
+ "mounts": [
87
+ {
88
+ "source": "/var/lib/docker/volumes/2419be4bd98f41a8e625c9e4479c1c5b0f8da4b5807f08a0340aa7a2e1574fdd/_data",
89
+ "volume": {
90
+ "name": "2419be4bd98f41a8e625c9e4479c1c5b0f8da4b5807f08a0340aa7a2e1574fdd",
91
+ "host": host.pk,
92
+ },
93
+ },
94
+ {
95
+ "source": "/var/lib/docker/volumes/844654ee4ac9d716679ed38b83c4ab6830a9db60ebf3fb2c000c7454bc41e9e2/_data",
96
+ "volume": {
97
+ "name": "844654ee4ac9d716679ed38b83c4ab6830a9db60ebf3fb2c000c7454bc41e9e2",
98
+ "host": host.pk,
99
+ },
100
+ },
101
+ ],
102
+ }
103
+ ],
104
+ format="json",
105
+ **self.header,
106
+ )
107
+
108
+ self.assertHttpStatus(response, status.HTTP_200_OK)
109
+
110
+ self.assertTrue(
111
+ Volume.objects.filter(
112
+ name="2419be4bd98f41a8e625c9e4479c1c5b0f8da4b5807f08a0340aa7a2e1574fdd",
113
+ host=host.pk,
114
+ ).exists()
115
+ )
116
+
117
+ self.assertTrue(
118
+ Volume.objects.filter(
119
+ name="844654ee4ac9d716679ed38b83c4ab6830a9db60ebf3fb2c000c7454bc41e9e2",
120
+ host=host.pk,
121
+ ).exists()
122
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: netbox-docker-plugin
3
- Version: 1.5.2
3
+ Version: 1.6.1
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
@@ -53,6 +53,8 @@ netbox_docker_plugin/migrations/0022_bind_bind_netbox_docker_plugin_bind_unique_
53
53
  netbox_docker_plugin/migrations/0023_delete_hosts.py
54
54
  netbox_docker_plugin/migrations/0024_registry_host_alter_registry_name_and_more.py
55
55
  netbox_docker_plugin/migrations/0025_alter_image_version.py
56
+ netbox_docker_plugin/migrations/0026_image_digest.py
57
+ netbox_docker_plugin/migrations/0027_container_restart_policy.py
56
58
  netbox_docker_plugin/migrations/__init__.py
57
59
  netbox_docker_plugin/models/__init__.py
58
60
  netbox_docker_plugin/models/container.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "netbox-docker-plugin"
7
- version = "1.5.2"
7
+ version = "1.6.1"
8
8
  authors = [
9
9
  { name="Vincent Simonin", email="vincent@saashup.com" },
10
10
  ]
@@ -1,44 +0,0 @@
1
- """Volume Test Case"""
2
-
3
- from utilities.testing import APIViewTestCases
4
- from netbox_docker_plugin.models.host import Host
5
- from netbox_docker_plugin.models.volume import Volume
6
- from netbox_docker_plugin.tests.base import BaseAPITestCase
7
-
8
-
9
- class VolumeApiTestCase(
10
- BaseAPITestCase,
11
- APIViewTestCases.GetObjectViewTestCase,
12
- APIViewTestCases.ListObjectsViewTestCase,
13
- APIViewTestCases.CreateObjectViewTestCase,
14
- APIViewTestCases.UpdateObjectViewTestCase,
15
- APIViewTestCases.DeleteObjectViewTestCase,
16
- ):
17
- """Volume Test Case Class"""
18
-
19
- model = Volume
20
- brief_fields = ["display", "driver", "id", "name", "url"]
21
-
22
- @classmethod
23
- def setUpTestData(cls) -> None:
24
- host1 = Host.objects.create(endpoint="http://localhost:8080", name="host1")
25
- host2 = Host.objects.create(endpoint="http://localhost:8080", name="host2")
26
-
27
- Volume.objects.create(host=host1, name="volume1")
28
- Volume.objects.create(host=host1, name="volume2")
29
- Volume.objects.create(host=host2, name="volume3")
30
-
31
- cls.create_data = [
32
- {
33
- "host": host1.pk,
34
- "name": "volume4",
35
- },
36
- {
37
- "host": host1.pk,
38
- "name": "volume5",
39
- },
40
- {
41
- "host": host2.pk,
42
- "name": "volume6",
43
- },
44
- ]