diff --git a/CHANGELOG.md b/CHANGELOG.md index e496d31d2..b82decb92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ v2.4.9 (FUTURE) * [#2400](https://github.com/digitalocean/netbox/issues/2400) - Correct representation of nested object assignment in API docs * [#2576](https://github.com/digitalocean/netbox/issues/2576) - Correct type for count_* fields in site API representation * [#2606](https://github.com/digitalocean/netbox/issues/2606) - Fixed filtering for interfaces with a virtual form factor +* [#2611](https://github.com/digitalocean/netbox/issues/2611) - Fix error handling when assigning a clustered device to a different site * [#2613](https://github.com/digitalocean/netbox/issues/2613) - Decrease live search minimum characters to three * [#2615](https://github.com/digitalocean/netbox/issues/2615) - Tweak live search widget to use brief format for API requests * [#2623](https://github.com/digitalocean/netbox/issues/2623) - Removed the need to pass the model class to the rqworker process for webhooks diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 46e039211..4a75ac386 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -20,7 +20,7 @@ from utilities.forms import ( ConfirmationForm, CSVChoiceField, ExpandableNameField, FilterChoiceField, FilterTreeNodeMultipleChoiceField, FlexibleModelChoiceField, JSONField, Livesearch, SelectWithDisabled, SelectWithPK, SmallTextarea, SlugField, ) -from virtualization.models import Cluster +from virtualization.models import Cluster, ClusterGroup from .constants import ( CONNECTION_STATUS_CHOICES, CONNECTION_STATUS_CONNECTED, DEVICE_STATUS_CHOICES, IFACE_FF_CHOICES, IFACE_FF_LAG, IFACE_MODE_ACCESS, IFACE_MODE_CHOICES, IFACE_MODE_TAGGED_ALL, IFACE_ORDERING_CHOICES, RACK_FACE_CHOICES, @@ -820,6 +820,23 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldForm): display_field='model' ) ) + cluster_group = forms.ModelChoiceField( + queryset=ClusterGroup.objects.all(), + required=False, + widget=forms.Select( + attrs={'filter-for': 'cluster', 'nullable': 'true'} + ) + ) + cluster = ChainedModelChoiceField( + queryset=Cluster.objects.all(), + chains=( + ('group', 'cluster_group'), + ), + required=False, + widget=APISelect( + api_url='/api/virtualization/clusters/?group_id={{cluster_group}}', + ) + ) comments = CommentField() tags = TagField(required=False) local_context_data = JSONField(required=False) @@ -828,8 +845,8 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldForm): model = Device fields = [ 'name', 'device_role', 'device_type', 'serial', 'asset_tag', 'site', 'rack', 'position', 'face', - 'status', 'platform', 'primary_ip4', 'primary_ip6', 'tenant_group', 'tenant', 'comments', 'tags', - 'local_context_data' + 'status', 'platform', 'primary_ip4', 'primary_ip6', 'cluster_group', 'cluster', 'tenant_group', 'tenant', + 'comments', 'tags', 'local_context_data' ] help_texts = { 'device_role': "The function this device serves", diff --git a/netbox/templates/dcim/device_edit.html b/netbox/templates/dcim/device_edit.html index 23b2b404e..1486c1ad5 100644 --- a/netbox/templates/dcim/device_edit.html +++ b/netbox/templates/dcim/device_edit.html @@ -62,6 +62,13 @@ {% endif %} +