netbox-docker-plugin 1.7.0__tar.gz → 1.8.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.
- {netbox_docker_plugin-1.7.0/netbox_docker_plugin.egg-info → netbox_docker_plugin-1.8.0}/PKG-INFO +2 -2
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/__init__.py +5 -3
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/container.py +2 -24
- netbox_docker_plugin-1.8.0/netbox_docker_plugin/migrations/0029_alter_container_state.py +20 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/container.py +35 -2
- netbox_docker_plugin-1.8.0/netbox_docker_plugin/signals.py +33 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/templates/netbox_docker_plugin/container.html +28 -4
- netbox_docker_plugin-1.8.0/netbox_docker_plugin/tests/container/test_container_actions.py +171 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/container/test_container_api.py +22 -3
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/container/test_container_operation_view.py +35 -10
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/container/test_container_validation.py +10 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/container/test_container_views.py +30 -9
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0/netbox_docker_plugin.egg-info}/PKG-INFO +2 -2
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin.egg-info/SOURCES.txt +3 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/pyproject.toml +2 -1
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/LICENSE +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/MANIFEST.in +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/README.md +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/api/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/api/serializers.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/api/urls.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/api/views.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/filtersets.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/bind.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/env.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/host.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/image.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/label.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/mount.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/network.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/network_setting.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/port.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/registry.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/volume.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0001_initial.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0002_image.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0003_image_size.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0004_volume.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0005_network.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0006_container_port_mount_label_env_and_more.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0007_remove_container_netbox_docker_plugin_container_unique_name_host__and_more.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0008_alter_network_unique_together_network_networkid_and_more.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0009_remove_container_network_networksettings_and_more.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0010_container_containerid_and_more.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0011_host_token.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0012_host_state.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0013_host_netbox_url.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0014_container_operation.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0015_remove_mount_netbox_docker_plugin_mount_unique_volume_and_more.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0016_alter_env_value.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0017_network_state.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0018_alter_mount_volume_alter_networksetting_network.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0019_host_agent_version_host_docker_api_version.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0020_container_hostname.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0021_registry_and_more.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0022_bind_bind_netbox_docker_plugin_bind_unique_bind.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0023_delete_hosts.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0024_registry_host_alter_registry_name_and_more.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0025_alter_image_version.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0026_image_digest.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0027_container_restart_policy.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/0028_mount_and_bind_read_only.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/migrations/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/host.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/image.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/network.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/registry.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/volume.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/navigation.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tables.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/templates/netbox_docker_plugin/host.html +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/templates/netbox_docker_plugin/image.html +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/templates/netbox_docker_plugin/network.html +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/templates/netbox_docker_plugin/registry.html +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/templates/netbox_docker_plugin/volume.html +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/templatetags/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/templatetags/host.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/base.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/container/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/host/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/host/test_host_api.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/host/test_host_views.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/host/test_replace_password.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/image/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/image/test_image_api.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/image/test_image_views.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/network/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/network/test_network_api.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/network/test_network_views.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/registry/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/registry/test_registry_api.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/registry/test_registry_views.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/test_init.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/volume/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/volume/test_volume_api.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/volume/test_volume_views.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/urls.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/utilities/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/__init__.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/bind.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/container.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/env.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/host.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/image.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/label.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/mount.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/network.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/network_setting.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/port.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/registry.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/volume.py +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin.egg-info/dependency_links.txt +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin.egg-info/top_level.txt +0 -0
- {netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/setup.cfg +0 -0
{netbox_docker_plugin-1.7.0/netbox_docker_plugin.egg-info → netbox_docker_plugin-1.8.0}/PKG-INFO
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: netbox-docker-plugin
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.8.0
|
|
4
4
|
Summary: Manage Docker with Netbox & style.
|
|
5
|
-
Author-email: Vincent Simonin <vincent@saashup.com>
|
|
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
|
|
7
7
|
Project-URL: Bug Tracker, https://github.com/SaaShup/netbox-docker-plugin/issues
|
|
8
8
|
Keywords: netbox,netbox-plugin,docker
|
|
@@ -10,12 +10,14 @@ class NetBoxDockerConfig(PluginConfig):
|
|
|
10
10
|
name = "netbox_docker_plugin"
|
|
11
11
|
verbose_name = " NetBox Docker Plugin"
|
|
12
12
|
description = "Manage Docker"
|
|
13
|
-
version = "1.
|
|
13
|
+
version = "1.8.0"
|
|
14
14
|
base_url = "docker"
|
|
15
|
-
author= "Vincent Simonin"
|
|
16
|
-
author_email= "vincent@saashup.com"
|
|
15
|
+
author= "Vincent Simonin <vincent@saashup.com>, David Delassus <david.jose.delassus@gmail.com>"
|
|
16
|
+
author_email= "vincent@saashup.com, david.jose.delassus@gmail.com"
|
|
17
17
|
|
|
18
18
|
def ready(self):
|
|
19
|
+
from . import signals # pylint: disable=unused-import, import-outside-toplevel
|
|
20
|
+
|
|
19
21
|
post_migrate.connect(create_webhook)
|
|
20
22
|
|
|
21
23
|
super().ready()
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/container.py
RENAMED
|
@@ -14,11 +14,7 @@ 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
|
|
18
|
-
Container,
|
|
19
|
-
ContainerStateChoices,
|
|
20
|
-
ContainerRestartPolicyChoices,
|
|
21
|
-
)
|
|
17
|
+
from ..models.container import Container, ContainerRestartPolicyChoices
|
|
22
18
|
from ..models.image import Image
|
|
23
19
|
|
|
24
20
|
|
|
@@ -44,7 +40,6 @@ class ContainerForm(NetBoxModelForm):
|
|
|
44
40
|
"image",
|
|
45
41
|
"name",
|
|
46
42
|
"hostname",
|
|
47
|
-
"state",
|
|
48
43
|
"restart_policy",
|
|
49
44
|
"tags",
|
|
50
45
|
)
|
|
@@ -53,7 +48,6 @@ class ContainerForm(NetBoxModelForm):
|
|
|
53
48
|
"host": "Host",
|
|
54
49
|
"image": "Image",
|
|
55
50
|
"hostname": "Hostname",
|
|
56
|
-
"state": "State",
|
|
57
51
|
"restart_policy": "Restart Policy",
|
|
58
52
|
}
|
|
59
53
|
|
|
@@ -79,9 +73,6 @@ class ContainerFilterForm(NetBoxModelFilterSetForm):
|
|
|
79
73
|
required=False,
|
|
80
74
|
label="Image",
|
|
81
75
|
)
|
|
82
|
-
state = forms.ChoiceField(
|
|
83
|
-
label="State", choices=ContainerStateChoices, required=False
|
|
84
|
-
)
|
|
85
76
|
restart_policy = forms.ChoiceField(
|
|
86
77
|
label="Restart Policy", choices=ContainerRestartPolicyChoices, required=False
|
|
87
78
|
)
|
|
@@ -91,13 +82,6 @@ class ContainerFilterForm(NetBoxModelFilterSetForm):
|
|
|
91
82
|
class ContainerImportForm(NetBoxModelImportForm):
|
|
92
83
|
"""Container importation form definition class"""
|
|
93
84
|
|
|
94
|
-
state = forms.ChoiceField(
|
|
95
|
-
label="State",
|
|
96
|
-
choices=ContainerStateChoices,
|
|
97
|
-
required=False,
|
|
98
|
-
help_text="Container State. Can be `created`, `restarting`, "
|
|
99
|
-
+ "`running`, `paused`, `exited` or `dead`.",
|
|
100
|
-
)
|
|
101
85
|
restart_policy = forms.ChoiceField(
|
|
102
86
|
label="Restart Policy",
|
|
103
87
|
choices=ContainerRestartPolicyChoices,
|
|
@@ -114,7 +98,6 @@ class ContainerImportForm(NetBoxModelImportForm):
|
|
|
114
98
|
"name",
|
|
115
99
|
"host",
|
|
116
100
|
"image",
|
|
117
|
-
"state",
|
|
118
101
|
"hostname",
|
|
119
102
|
)
|
|
120
103
|
labels = {
|
|
@@ -127,11 +110,6 @@ class ContainerImportForm(NetBoxModelImportForm):
|
|
|
127
110
|
class ContainerBulkEditForm(NetBoxModelBulkEditForm):
|
|
128
111
|
"""Container bulk edit form definition class"""
|
|
129
112
|
|
|
130
|
-
state = forms.ChoiceField(
|
|
131
|
-
label="State",
|
|
132
|
-
choices=ContainerStateChoices,
|
|
133
|
-
required=True,
|
|
134
|
-
)
|
|
135
113
|
restart_policy = forms.ChoiceField(
|
|
136
114
|
label="Restart Policy",
|
|
137
115
|
choices=ContainerRestartPolicyChoices,
|
|
@@ -142,7 +120,7 @@ class ContainerBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
142
120
|
)
|
|
143
121
|
|
|
144
122
|
model = Container
|
|
145
|
-
fieldsets = (("General", ("
|
|
123
|
+
fieldsets = (("General", ("restart_policy", "hostname")),)
|
|
146
124
|
|
|
147
125
|
|
|
148
126
|
class ContainerOperationForm(NetBoxModelForm):
|
|
@@ -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", "0028_mount_and_bind_read_only"),
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
operations = [
|
|
15
|
+
migrations.AlterField(
|
|
16
|
+
model_name="container",
|
|
17
|
+
name="state",
|
|
18
|
+
field=models.CharField(default="none", max_length=32),
|
|
19
|
+
),
|
|
20
|
+
]
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/container.py
RENAMED
|
@@ -16,7 +16,7 @@ from utilities.choices import ChoiceSet
|
|
|
16
16
|
from utilities.querysets import RestrictedQuerySet
|
|
17
17
|
from netbox.models import NetBoxModel
|
|
18
18
|
from .image import Image
|
|
19
|
-
from .host import Host
|
|
19
|
+
from .host import Host, HostStateChoices
|
|
20
20
|
from .network import Network
|
|
21
21
|
from .volume import Volume
|
|
22
22
|
|
|
@@ -26,7 +26,7 @@ class ContainerStateChoices(ChoiceSet):
|
|
|
26
26
|
|
|
27
27
|
key = "Container.state"
|
|
28
28
|
|
|
29
|
-
DEFAULT_VALUE = "
|
|
29
|
+
DEFAULT_VALUE = "none"
|
|
30
30
|
|
|
31
31
|
CHOICES = [
|
|
32
32
|
("created", "Created", "dark"),
|
|
@@ -133,6 +133,39 @@ class Container(NetBoxModel):
|
|
|
133
133
|
default=ContainerRestartPolicyChoices.DEFAULT_VALUE,
|
|
134
134
|
)
|
|
135
135
|
|
|
136
|
+
@property
|
|
137
|
+
def can_create(self) -> bool:
|
|
138
|
+
""" Check if the container can be created """
|
|
139
|
+
return self.state == "none"
|
|
140
|
+
|
|
141
|
+
@property
|
|
142
|
+
def can_start(self) -> bool:
|
|
143
|
+
""" Check if the container can be started """
|
|
144
|
+
return self.state in ["created", "exited", "dead"]
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def can_stop(self) -> bool:
|
|
148
|
+
""" Check if the container can be stopped """
|
|
149
|
+
return self.state in ["running"]
|
|
150
|
+
|
|
151
|
+
@property
|
|
152
|
+
def can_restart(self) -> bool:
|
|
153
|
+
""" Check if the container can be restarted """
|
|
154
|
+
return self.state in ["running"]
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def can_recreate(self) -> bool:
|
|
158
|
+
""" Check if the container can be recreated """
|
|
159
|
+
return self.state in ["created", "running", "exited", "dead"]
|
|
160
|
+
|
|
161
|
+
@property
|
|
162
|
+
def can_delete(self) -> bool:
|
|
163
|
+
""" Check if the container can be deleted """
|
|
164
|
+
return (
|
|
165
|
+
self.host.state == HostStateChoices.STATE_DELETED
|
|
166
|
+
or self.state in ["created", "paused", "exited", "dead"]
|
|
167
|
+
)
|
|
168
|
+
|
|
136
169
|
class Meta:
|
|
137
170
|
"""Image Model Meta Class"""
|
|
138
171
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
""" Hooks on Django model signals. """
|
|
2
|
+
|
|
3
|
+
from django.db.models.signals import pre_delete, pre_save
|
|
4
|
+
from django.dispatch import receiver
|
|
5
|
+
from utilities.exceptions import AbortRequest
|
|
6
|
+
|
|
7
|
+
from .models import Container
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@receiver(pre_delete, sender=Container)
|
|
11
|
+
def prevent_deleting_running_containers(instance, **_kwargs):
|
|
12
|
+
""" Abort deletion if container is running. """
|
|
13
|
+
|
|
14
|
+
if not instance.can_delete:
|
|
15
|
+
raise AbortRequest(
|
|
16
|
+
f"The container {instance.name} is running, please stop it before deletion"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@receiver(pre_save, sender=Container)
|
|
21
|
+
def restrict_container_actions(instance, **_kwargs):
|
|
22
|
+
""" Check if the container's state is correct for the given action """
|
|
23
|
+
|
|
24
|
+
if any([
|
|
25
|
+
instance.operation == "create" and not instance.can_create,
|
|
26
|
+
instance.operation == "start" and not instance.can_start,
|
|
27
|
+
instance.operation == "restart" and not instance.can_restart,
|
|
28
|
+
instance.operation == "stop" and not instance.can_stop,
|
|
29
|
+
instance.operation == "recreate" and not instance.can_recreate,
|
|
30
|
+
]):
|
|
31
|
+
raise AbortRequest(
|
|
32
|
+
f"Cannot {instance.operation} container {instance.name} in state {instance.state}"
|
|
33
|
+
)
|
|
@@ -6,7 +6,13 @@
|
|
|
6
6
|
<form action="{% url 'plugins:netbox_docker_plugin:container_operation' pk=object.id operation='start' %}" method="post">
|
|
7
7
|
{% csrf_token %}
|
|
8
8
|
<input type="hidden" name="operation" value="start">
|
|
9
|
-
<button
|
|
9
|
+
<button
|
|
10
|
+
type="submit"
|
|
11
|
+
class="btn btn-sm btn-success"
|
|
12
|
+
{% if not object.can_start %}
|
|
13
|
+
disabled
|
|
14
|
+
{% endif %}
|
|
15
|
+
>
|
|
10
16
|
<i class="mdi mdi-play"></i> Start
|
|
11
17
|
</button>
|
|
12
18
|
</form>
|
|
@@ -14,7 +20,13 @@
|
|
|
14
20
|
<form action="{% url 'plugins:netbox_docker_plugin:container_operation' pk=object.id operation='stop' %}" method="post">
|
|
15
21
|
{% csrf_token %}
|
|
16
22
|
<input type="hidden" name="operation" value="stop">
|
|
17
|
-
<button
|
|
23
|
+
<button
|
|
24
|
+
type="submit"
|
|
25
|
+
class="btn btn-sm btn-danger"
|
|
26
|
+
{% if not object.can_stop %}
|
|
27
|
+
disabled
|
|
28
|
+
{% endif %}
|
|
29
|
+
>
|
|
18
30
|
<i class="mdi mdi-stop"></i> Stop
|
|
19
31
|
</button>
|
|
20
32
|
</form>
|
|
@@ -22,7 +34,13 @@
|
|
|
22
34
|
<form action="{% url 'plugins:netbox_docker_plugin:container_operation' pk=object.id operation='restart' %}" method="post">
|
|
23
35
|
{% csrf_token %}
|
|
24
36
|
<input type="hidden" name="operation" value="restart">
|
|
25
|
-
<button
|
|
37
|
+
<button
|
|
38
|
+
type="submit"
|
|
39
|
+
class="btn btn-sm btn-light"
|
|
40
|
+
{% if not object.can_restart %}
|
|
41
|
+
disabled
|
|
42
|
+
{% endif %}
|
|
43
|
+
>
|
|
26
44
|
<i class="mdi mdi-restart"></i> Restart
|
|
27
45
|
</button>
|
|
28
46
|
</form>
|
|
@@ -30,7 +48,13 @@
|
|
|
30
48
|
<form action="{% url 'plugins:netbox_docker_plugin:container_operation' pk=object.id operation='recreate' %}" method="post">
|
|
31
49
|
{% csrf_token %}
|
|
32
50
|
<input type="hidden" name="operation" value="recreate">
|
|
33
|
-
<button
|
|
51
|
+
<button
|
|
52
|
+
type="submit"
|
|
53
|
+
class="btn btn-sm btn-dark"
|
|
54
|
+
{% if not object.can_recreate %}
|
|
55
|
+
disabled
|
|
56
|
+
{% endif %}
|
|
57
|
+
>
|
|
34
58
|
<i class="mdi mdi-autorenew"></i> Recreate
|
|
35
59
|
</button>
|
|
36
60
|
</form>
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
""" Container action restrictions test suite """
|
|
2
|
+
|
|
3
|
+
from django.db import transaction
|
|
4
|
+
from django.test import TestCase
|
|
5
|
+
from utilities.exceptions import AbortRequest
|
|
6
|
+
from netbox_docker_plugin.models.container import Container
|
|
7
|
+
from netbox_docker_plugin.models.host import Host, HostStateChoices
|
|
8
|
+
from netbox_docker_plugin.models.image import Image
|
|
9
|
+
from netbox_docker_plugin.models.registry import Registry
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ContainerActionTestCase(TestCase):
|
|
13
|
+
""" Test the various scenarii of container actions """
|
|
14
|
+
|
|
15
|
+
objects = {}
|
|
16
|
+
|
|
17
|
+
def test_allowed_operations(self):
|
|
18
|
+
""" Test that only specific operations are allowed according to a state """
|
|
19
|
+
|
|
20
|
+
cases = [
|
|
21
|
+
("create", ["none"]),
|
|
22
|
+
("start", ["created", "exited", "dead"]),
|
|
23
|
+
("stop", ["running"]),
|
|
24
|
+
("restart", ["running"]),
|
|
25
|
+
("recreate", ["created", "exited", "dead", "running"]),
|
|
26
|
+
("noop", ["created", "restarting", "running", "paused", "exited", "dead", "none"]),
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
for operation, states in cases:
|
|
30
|
+
for state in states:
|
|
31
|
+
with self.subTest(operation=operation, state=state):
|
|
32
|
+
with transaction.atomic():
|
|
33
|
+
name = f"container-{operation}-{state}"
|
|
34
|
+
obj = Container.objects.create(
|
|
35
|
+
host=self.objects["host1"],
|
|
36
|
+
image=self.objects["image2"],
|
|
37
|
+
name=name,
|
|
38
|
+
operation="none",
|
|
39
|
+
state=state,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
obj.operation = operation
|
|
43
|
+
obj.save()
|
|
44
|
+
|
|
45
|
+
self.assertEqual(
|
|
46
|
+
Container.objects.get(name=name).operation,
|
|
47
|
+
operation,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
def test_forbidden_operations(self):
|
|
51
|
+
""" Test that forbidden operations raise an AbortRequest """
|
|
52
|
+
|
|
53
|
+
cases = [
|
|
54
|
+
("create", ["created", "restarting", "running", "paused", "exited", "dead"]),
|
|
55
|
+
("start", ["running", "restarting", "paused", "none"]),
|
|
56
|
+
("stop", ["created", "restarting", "paused", "exited", "dead", "none"]),
|
|
57
|
+
("restart", ["created", "restarting", "paused", "exited", "dead", "none"]),
|
|
58
|
+
("recreate", ["restarting", "paused", "none"]),
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
for operation, states in cases:
|
|
62
|
+
for state in states:
|
|
63
|
+
with self.subTest(operation=operation, state=state):
|
|
64
|
+
with transaction.atomic():
|
|
65
|
+
with self.assertRaises(
|
|
66
|
+
AbortRequest,
|
|
67
|
+
msg=f"AbortRequest not raised for {state}",
|
|
68
|
+
):
|
|
69
|
+
name = f"container-{operation}-{state}"
|
|
70
|
+
obj = Container.objects.create(
|
|
71
|
+
host=self.objects["host1"],
|
|
72
|
+
image=self.objects["image2"],
|
|
73
|
+
name=name,
|
|
74
|
+
operation="none",
|
|
75
|
+
state=state,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
obj.operation = operation
|
|
79
|
+
obj.save()
|
|
80
|
+
|
|
81
|
+
def test_delete_non_running_container(self):
|
|
82
|
+
""" Test that a non running container can be deleted """
|
|
83
|
+
|
|
84
|
+
for state in ["created", "paused", "exited", "dead"]:
|
|
85
|
+
with self.subTest(operation="delete", state=state):
|
|
86
|
+
with transaction.atomic():
|
|
87
|
+
name = f"container-delete-{state}"
|
|
88
|
+
obj = Container.objects.create(
|
|
89
|
+
host=self.objects["host1"],
|
|
90
|
+
image=self.objects["image2"],
|
|
91
|
+
name=name,
|
|
92
|
+
operation="none",
|
|
93
|
+
state=state,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
obj.delete()
|
|
97
|
+
|
|
98
|
+
self.assertFalse(Container.objects.filter(name=name).exists())
|
|
99
|
+
|
|
100
|
+
def test_delete_running_container(self):
|
|
101
|
+
""" Test that a running container cannot be deleted """
|
|
102
|
+
|
|
103
|
+
for state in ["running", "restarting", "none"]:
|
|
104
|
+
with self.subTest(operation="delete", state=state):
|
|
105
|
+
with transaction.atomic():
|
|
106
|
+
with self.assertRaises(
|
|
107
|
+
AbortRequest,
|
|
108
|
+
msg=f"AbortRequest not raised for {state}",
|
|
109
|
+
):
|
|
110
|
+
name = f"container-delete-{state}"
|
|
111
|
+
obj = Container.objects.create(
|
|
112
|
+
host=self.objects["host1"],
|
|
113
|
+
image=self.objects["image2"],
|
|
114
|
+
name=name,
|
|
115
|
+
operation="none",
|
|
116
|
+
state=state,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
obj.delete()
|
|
120
|
+
|
|
121
|
+
def test_delete_container_on_deleted_host(self):
|
|
122
|
+
""" Test that a container on a deleted host can be deleted """
|
|
123
|
+
|
|
124
|
+
for state in ["created", "running", "restarted", "paused", "exited", "dead", "none"]:
|
|
125
|
+
with self.subTest(operation="delete", state=state):
|
|
126
|
+
with transaction.atomic():
|
|
127
|
+
name = f"container-delete-{state}"
|
|
128
|
+
obj = Container.objects.create(
|
|
129
|
+
host=self.objects["host2"],
|
|
130
|
+
image=self.objects["image2"],
|
|
131
|
+
name=name,
|
|
132
|
+
operation="none",
|
|
133
|
+
state=state,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
obj.delete()
|
|
137
|
+
|
|
138
|
+
self.assertFalse(Container.objects.filter(name=name).exists())
|
|
139
|
+
|
|
140
|
+
@classmethod
|
|
141
|
+
def setUpTestData(cls):
|
|
142
|
+
cls.objects["host1"] = Host.objects.create(
|
|
143
|
+
endpoint="http://localhost:8080",
|
|
144
|
+
name="host1",
|
|
145
|
+
)
|
|
146
|
+
cls.objects["registry1"] = Registry.objects.create(
|
|
147
|
+
host=cls.objects["host1"],
|
|
148
|
+
name="registry1",
|
|
149
|
+
serveraddress="http://localhost:8080",
|
|
150
|
+
)
|
|
151
|
+
cls.objects["image2"] = Image.objects.create(
|
|
152
|
+
host=cls.objects["host1"],
|
|
153
|
+
registry=cls.objects["registry1"],
|
|
154
|
+
name="image2",
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
cls.objects["host2"] = Host.objects.create(
|
|
158
|
+
endpoint="http://localhost:8080",
|
|
159
|
+
name="host2",
|
|
160
|
+
state=HostStateChoices.STATE_DELETED,
|
|
161
|
+
)
|
|
162
|
+
cls.objects["registry2"] = Registry.objects.create(
|
|
163
|
+
host=cls.objects["host2"],
|
|
164
|
+
name="registry2",
|
|
165
|
+
serveraddress="http://localhost:8080",
|
|
166
|
+
)
|
|
167
|
+
cls.objects["image2"] = Image.objects.create(
|
|
168
|
+
host=cls.objects["host2"],
|
|
169
|
+
registry=cls.objects["registry2"],
|
|
170
|
+
name="image2",
|
|
171
|
+
)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# pylint: disable=R0801
|
|
1
2
|
"""Container Test Case"""
|
|
2
3
|
|
|
3
4
|
from utilities.testing import APIViewTestCases
|
|
@@ -64,9 +65,27 @@ class ContainerApiTestCase(
|
|
|
64
65
|
volume2 = Volume.objects.create(host=host1, name="volume2")
|
|
65
66
|
volume3 = Volume.objects.create(host=host2, name="volume3")
|
|
66
67
|
|
|
67
|
-
Container.objects.create(
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
Container.objects.create(
|
|
69
|
+
host=host1,
|
|
70
|
+
image=image1,
|
|
71
|
+
name="container1",
|
|
72
|
+
operation="none",
|
|
73
|
+
state="created",
|
|
74
|
+
)
|
|
75
|
+
Container.objects.create(
|
|
76
|
+
host=host1,
|
|
77
|
+
image=image1,
|
|
78
|
+
name="container2",
|
|
79
|
+
operation="none",
|
|
80
|
+
state="created",
|
|
81
|
+
)
|
|
82
|
+
Container.objects.create(
|
|
83
|
+
host=host2,
|
|
84
|
+
image=image2,
|
|
85
|
+
name="container3",
|
|
86
|
+
operation="none",
|
|
87
|
+
state="created",
|
|
88
|
+
)
|
|
70
89
|
|
|
71
90
|
cls.create_data = [
|
|
72
91
|
{
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# pylint: disable=R0801
|
|
1
2
|
"""Container operation Views Test Case"""
|
|
2
3
|
|
|
3
4
|
from django.urls import reverse
|
|
@@ -22,7 +23,7 @@ class ContainerViewsTestCase(BaseModelViewTestCase, ModelViewTestCase):
|
|
|
22
23
|
|
|
23
24
|
def test_operation_start_object_without_permission(self):
|
|
24
25
|
"""Test operation start object without permission"""
|
|
25
|
-
instance = self._get_queryset().first()
|
|
26
|
+
instance = self._get_queryset().exclude(state="running").first()
|
|
26
27
|
|
|
27
28
|
# Try GET without permission
|
|
28
29
|
with disable_warnings("django.request"):
|
|
@@ -42,7 +43,7 @@ class ContainerViewsTestCase(BaseModelViewTestCase, ModelViewTestCase):
|
|
|
42
43
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
43
44
|
def test_operation_start_object_with_permission(self):
|
|
44
45
|
"""Test operation start object with permission""" """ """
|
|
45
|
-
instance = self._get_queryset().first()
|
|
46
|
+
instance = self._get_queryset().exclude(state="running").first()
|
|
46
47
|
|
|
47
48
|
# Assign model-level permission
|
|
48
49
|
obj_perm = ObjectPermission(name="Test permission", actions=["change"])
|
|
@@ -78,7 +79,7 @@ class ContainerViewsTestCase(BaseModelViewTestCase, ModelViewTestCase):
|
|
|
78
79
|
|
|
79
80
|
def test_operation_stop_object_without_permission(self):
|
|
80
81
|
"""Test operation stop object without permission"""
|
|
81
|
-
instance = self._get_queryset().first()
|
|
82
|
+
instance = self._get_queryset().filter(state="running").first()
|
|
82
83
|
|
|
83
84
|
# Try GET without permission
|
|
84
85
|
with disable_warnings("django.request"):
|
|
@@ -98,7 +99,7 @@ class ContainerViewsTestCase(BaseModelViewTestCase, ModelViewTestCase):
|
|
|
98
99
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
99
100
|
def test_operation_stop_object_with_permission(self):
|
|
100
101
|
"""Test operation stop object with permission""" """ """
|
|
101
|
-
instance = self._get_queryset().first()
|
|
102
|
+
instance = self._get_queryset().filter(state="running").first()
|
|
102
103
|
|
|
103
104
|
# Assign model-level permission
|
|
104
105
|
obj_perm = ObjectPermission(name="Test permission", actions=["change"])
|
|
@@ -134,7 +135,7 @@ class ContainerViewsTestCase(BaseModelViewTestCase, ModelViewTestCase):
|
|
|
134
135
|
|
|
135
136
|
def test_operation_restart_object_without_permission(self):
|
|
136
137
|
"""Test operation restart object without permission"""
|
|
137
|
-
instance = self._get_queryset().first()
|
|
138
|
+
instance = self._get_queryset().filter(state="running").first()
|
|
138
139
|
|
|
139
140
|
# Try GET without permission
|
|
140
141
|
with disable_warnings("django.request"):
|
|
@@ -154,7 +155,7 @@ class ContainerViewsTestCase(BaseModelViewTestCase, ModelViewTestCase):
|
|
|
154
155
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
155
156
|
def test_operation_restart_object_with_permission(self):
|
|
156
157
|
"""Test operation restart object with permission""" """ """
|
|
157
|
-
instance = self._get_queryset().first()
|
|
158
|
+
instance = self._get_queryset().filter(state="running").first()
|
|
158
159
|
|
|
159
160
|
# Assign model-level permission
|
|
160
161
|
obj_perm = ObjectPermission(name="Test permission", actions=["change"])
|
|
@@ -259,7 +260,31 @@ class ContainerViewsTestCase(BaseModelViewTestCase, ModelViewTestCase):
|
|
|
259
260
|
image1 = Image.objects.create(host=host1, name="image1", registry=registry1)
|
|
260
261
|
image2 = Image.objects.create(host=host2, name="image2", registry=registry2)
|
|
261
262
|
|
|
262
|
-
Container.objects.create(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
263
|
+
Container.objects.create(
|
|
264
|
+
host=host1,
|
|
265
|
+
image=image1,
|
|
266
|
+
name="container1",
|
|
267
|
+
operation="none",
|
|
268
|
+
state="created",
|
|
269
|
+
)
|
|
270
|
+
Container.objects.create(
|
|
271
|
+
host=host1,
|
|
272
|
+
image=image1,
|
|
273
|
+
name="container2",
|
|
274
|
+
operation="none",
|
|
275
|
+
state="created",
|
|
276
|
+
)
|
|
277
|
+
Container.objects.create(
|
|
278
|
+
host=host2,
|
|
279
|
+
image=image2,
|
|
280
|
+
name="container3",
|
|
281
|
+
operation="none",
|
|
282
|
+
state="created",
|
|
283
|
+
)
|
|
284
|
+
Container.objects.create(
|
|
285
|
+
host=host2,
|
|
286
|
+
image=image2,
|
|
287
|
+
name="container4",
|
|
288
|
+
operation="none",
|
|
289
|
+
state="running",
|
|
290
|
+
)
|
|
@@ -23,6 +23,8 @@ class ContainerValidationTestCase(TestCase):
|
|
|
23
23
|
host=self.objects["host1"],
|
|
24
24
|
image=self.objects["image1"],
|
|
25
25
|
name="container1",
|
|
26
|
+
operation="none",
|
|
27
|
+
state="created",
|
|
26
28
|
)
|
|
27
29
|
|
|
28
30
|
self.assertTrue(isinstance(container.id, int))
|
|
@@ -31,6 +33,8 @@ class ContainerValidationTestCase(TestCase):
|
|
|
31
33
|
host=self.objects["host2"],
|
|
32
34
|
image=self.objects["image2"],
|
|
33
35
|
name="container2",
|
|
36
|
+
operation="none",
|
|
37
|
+
state="created",
|
|
34
38
|
)
|
|
35
39
|
|
|
36
40
|
self.assertTrue(isinstance(container.id, int))
|
|
@@ -43,6 +47,8 @@ class ContainerValidationTestCase(TestCase):
|
|
|
43
47
|
host=self.objects["host1"],
|
|
44
48
|
image=self.objects["image2"],
|
|
45
49
|
name="container2",
|
|
50
|
+
operation="none",
|
|
51
|
+
state="created",
|
|
46
52
|
)
|
|
47
53
|
container.clean()
|
|
48
54
|
|
|
@@ -63,6 +69,8 @@ class ContainerValidationTestCase(TestCase):
|
|
|
63
69
|
host=self.objects["host1"],
|
|
64
70
|
image=self.objects["image1"],
|
|
65
71
|
name="container3",
|
|
72
|
+
operation="none",
|
|
73
|
+
state="created",
|
|
66
74
|
)
|
|
67
75
|
|
|
68
76
|
mount = Mount(
|
|
@@ -88,6 +96,8 @@ class ContainerValidationTestCase(TestCase):
|
|
|
88
96
|
host=self.objects["host1"],
|
|
89
97
|
image=self.objects["image1"],
|
|
90
98
|
name="container3",
|
|
99
|
+
operation="none",
|
|
100
|
+
state="created",
|
|
91
101
|
)
|
|
92
102
|
|
|
93
103
|
network_setting = NetworkSetting(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# pylint: disable=R0801
|
|
1
2
|
"""Container Views Test Case"""
|
|
2
3
|
|
|
3
4
|
from utilities.testing import ViewTestCases
|
|
@@ -31,19 +32,39 @@ class ContainerViewsTestCase(
|
|
|
31
32
|
image2 = Image.objects.create(host=host2, name="image2", registry=registry2)
|
|
32
33
|
|
|
33
34
|
container1 = Container.objects.create(
|
|
34
|
-
host=host1,
|
|
35
|
+
host=host1,
|
|
36
|
+
image=image1,
|
|
37
|
+
name="container1",
|
|
38
|
+
restart_policy="always",
|
|
39
|
+
operation="none",
|
|
40
|
+
state="created",
|
|
35
41
|
)
|
|
36
42
|
container2 = Container.objects.create(
|
|
37
|
-
host=host1,
|
|
43
|
+
host=host1,
|
|
44
|
+
image=image1,
|
|
45
|
+
name="container2",
|
|
46
|
+
operation="none",
|
|
47
|
+
state="created",
|
|
48
|
+
)
|
|
49
|
+
Container.objects.create(
|
|
50
|
+
host=host2,
|
|
51
|
+
image=image2,
|
|
52
|
+
name="container3",
|
|
53
|
+
operation="none",
|
|
54
|
+
state="created",
|
|
55
|
+
)
|
|
56
|
+
Container.objects.create(
|
|
57
|
+
host=host2,
|
|
58
|
+
image=image2,
|
|
59
|
+
name="container4",
|
|
60
|
+
operation="none",
|
|
61
|
+
state="created",
|
|
38
62
|
)
|
|
39
|
-
Container.objects.create(host=host2, image=image2, name="container3")
|
|
40
|
-
Container.objects.create(host=host2, image=image2, name="container4")
|
|
41
63
|
|
|
42
64
|
cls.form_data = {
|
|
43
65
|
"name": "container5",
|
|
44
66
|
"host": host1.pk,
|
|
45
67
|
"image": image1.pk,
|
|
46
|
-
"state": "created",
|
|
47
68
|
"restart_policy": "unless-stopped",
|
|
48
69
|
}
|
|
49
70
|
|
|
@@ -54,12 +75,12 @@ class ContainerViewsTestCase(
|
|
|
54
75
|
)
|
|
55
76
|
|
|
56
77
|
cls.bulk_edit_data = {
|
|
57
|
-
"
|
|
78
|
+
"hostname": "h",
|
|
58
79
|
"restart_policy": "always",
|
|
59
80
|
}
|
|
60
81
|
|
|
61
82
|
cls.csv_update_data = (
|
|
62
|
-
"id,name,host,image,
|
|
63
|
-
f"{container1.pk},container1,{host1.pk},{image1.pk}
|
|
64
|
-
f"{container2.pk},container2,{host1.pk},{image1.pk},
|
|
83
|
+
"id,name,host,image,hostname,restart_policy",
|
|
84
|
+
f"{container1.pk},container1,{host1.pk},{image1.pk},,on-failure",
|
|
85
|
+
f"{container2.pk},container2,{host1.pk},{image1.pk},container2,unless-stopped",
|
|
65
86
|
)
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0/netbox_docker_plugin.egg-info}/PKG-INFO
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: netbox-docker-plugin
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.8.0
|
|
4
4
|
Summary: Manage Docker with Netbox & style.
|
|
5
|
-
Author-email: Vincent Simonin <vincent@saashup.com>
|
|
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
|
|
7
7
|
Project-URL: Bug Tracker, https://github.com/SaaShup/netbox-docker-plugin/issues
|
|
8
8
|
Keywords: netbox,netbox-plugin,docker
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin.egg-info/SOURCES.txt
RENAMED
|
@@ -5,6 +5,7 @@ pyproject.toml
|
|
|
5
5
|
netbox_docker_plugin/__init__.py
|
|
6
6
|
netbox_docker_plugin/filtersets.py
|
|
7
7
|
netbox_docker_plugin/navigation.py
|
|
8
|
+
netbox_docker_plugin/signals.py
|
|
8
9
|
netbox_docker_plugin/tables.py
|
|
9
10
|
netbox_docker_plugin/urls.py
|
|
10
11
|
netbox_docker_plugin.egg-info/PKG-INFO
|
|
@@ -56,6 +57,7 @@ netbox_docker_plugin/migrations/0025_alter_image_version.py
|
|
|
56
57
|
netbox_docker_plugin/migrations/0026_image_digest.py
|
|
57
58
|
netbox_docker_plugin/migrations/0027_container_restart_policy.py
|
|
58
59
|
netbox_docker_plugin/migrations/0028_mount_and_bind_read_only.py
|
|
60
|
+
netbox_docker_plugin/migrations/0029_alter_container_state.py
|
|
59
61
|
netbox_docker_plugin/migrations/__init__.py
|
|
60
62
|
netbox_docker_plugin/models/__init__.py
|
|
61
63
|
netbox_docker_plugin/models/container.py
|
|
@@ -76,6 +78,7 @@ netbox_docker_plugin/tests/__init__.py
|
|
|
76
78
|
netbox_docker_plugin/tests/base.py
|
|
77
79
|
netbox_docker_plugin/tests/test_init.py
|
|
78
80
|
netbox_docker_plugin/tests/container/__init__.py
|
|
81
|
+
netbox_docker_plugin/tests/container/test_container_actions.py
|
|
79
82
|
netbox_docker_plugin/tests/container/test_container_api.py
|
|
80
83
|
netbox_docker_plugin/tests/container/test_container_operation_view.py
|
|
81
84
|
netbox_docker_plugin/tests/container/test_container_validation.py
|
|
@@ -4,9 +4,10 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "netbox-docker-plugin"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.8.0"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Vincent Simonin", email="vincent@saashup.com" },
|
|
10
|
+
{ name="David Delassus", email="david.jose.delassus@gmail.com" }
|
|
10
11
|
]
|
|
11
12
|
description = "Manage Docker with Netbox & style."
|
|
12
13
|
readme = "README.md"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/api/__init__.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/api/serializers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/filtersets.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/__init__.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/bind.py
RENAMED
|
File without changes
|
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/host.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/image.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/label.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/mount.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/network.py
RENAMED
|
File without changes
|
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/port.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/registry.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/forms/volume.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/__init__.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/host.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/image.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/network.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/registry.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/models/volume.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/navigation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/templatetags/host.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/__init__.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/tests/test_init.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/utilities/__init__.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/__init__.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/bind.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/container.py
RENAMED
|
File without changes
|
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/host.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/image.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/label.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/mount.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/network.py
RENAMED
|
File without changes
|
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/port.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/registry.py
RENAMED
|
File without changes
|
{netbox_docker_plugin-1.7.0 → netbox_docker_plugin-1.8.0}/netbox_docker_plugin/views/volume.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|