diff --git a/docs/release-notes/version-2.7.md b/docs/release-notes/version-2.7.md index afa43cade..112947751 100644 --- a/docs/release-notes/version-2.7.md +++ b/docs/release-notes/version-2.7.md @@ -8,6 +8,7 @@ ## Bug Fixes +* [#3950](https://github.com/netbox-community/netbox/issues/3950) - Automatically select parent manufacturer when specifying initial device type during device creation * [#3982](https://github.com/netbox-community/netbox/issues/3982) - Restore tooltip for reservations on rack elevations * [#3983](https://github.com/netbox-community/netbox/issues/3983) - Permit the creation of multiple unnamed devices * [#3989](https://github.com/netbox-community/netbox/issues/3989) - Correct HTTP content type assignment for webhooks diff --git a/netbox/dcim/fixtures/dcim.json b/netbox/dcim/fixtures/dcim.json index b9f41edb5..2b379b9ff 100644 --- a/netbox/dcim/fixtures/dcim.json +++ b/netbox/dcim/fixtures/dcim.json @@ -66,6 +66,14 @@ "slug": "servertech" } }, +{ + "model": "dcim.manufacturer", + "pk": 4, + "fields": { + "name": "Dell", + "slug": "dell" + } +}, { "model": "dcim.devicetype", "pk": 1, @@ -144,6 +152,19 @@ "is_full_depth": false } }, +{ + "model": "dcim.devicetype", + "pk": 7, + "fields": { + "created": "2016-06-23", + "last_updated": "2016-06-23T03:19:56.521Z", + "manufacturer": 4, + "model": "PowerEdge R640", + "slug": "poweredge-r640", + "u_height": 1, + "is_full_depth": false + } +}, { "model": "dcim.consoleporttemplate", "pk": 1, @@ -1880,6 +1901,15 @@ "color": "yellow" } }, +{ + "model": "dcim.devicerole", + "pk": 7, + "fields": { + "name": "Server", + "slug": "server", + "color": "grey" + } +}, { "model": "dcim.platform", "pk": 1, @@ -2127,6 +2157,34 @@ "comments": "" } }, +{ + "model": "dcim.device", + "pk": 13, + "fields": { + "local_context_data": null, + "created": "2016-06-23", + "last_updated": "2016-06-23T03:19:56.521Z", + "device_type": 7, + "device_role": 6, + "tenant": null, + "platform": null, + "name": "test1-server1", + "serial": "", + "asset_tag": null, + "site": 1, + "rack": 2, + "position": null, + "face": "", + "status": true, + "primary_ip4": null, + "primary_ip6": null, + "cluster": 4, + "virtual_chassis": null, + "vc_position": null, + "vc_priority": null, + "comments": "" + } +}, { "model": "dcim.consoleport", "pk": 1, diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 84d83a94c..79fe13a9a 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1642,6 +1642,16 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldForm): if instance and instance.cluster is not None: kwargs['initial']['cluster_group'] = instance.cluster.group + if 'device_type' in kwargs['initial'] and 'manufacturer' not in kwargs['initial']: + device_type_id = kwargs['initial']['device_type'] + manufacturer_id = DeviceType.objects.filter(pk=device_type_id).values_list('manufacturer__pk', flat=True).first() + kwargs['initial']['manufacturer'] = manufacturer_id + + if 'cluster' in kwargs['initial'] and 'cluster_group' not in kwargs['initial']: + cluster_id = kwargs['initial']['cluster'] + cluster_group_id = Cluster.objects.filter(pk=cluster_id).values_list('group__pk', flat=True).first() + kwargs['initial']['cluster_group'] = cluster_group_id + super().__init__(*args, **kwargs) if self.instance.pk: diff --git a/netbox/dcim/tests/test_forms.py b/netbox/dcim/tests/test_forms.py index d7a946568..5bbe36716 100644 --- a/netbox/dcim/tests/test_forms.py +++ b/netbox/dcim/tests/test_forms.py @@ -10,7 +10,7 @@ def get_id(model, slug): class DeviceTestCase(TestCase): - fixtures = ['dcim', 'ipam'] + fixtures = ['dcim', 'ipam', 'virtualization'] def test_racked_device(self): test = DeviceForm(data={ @@ -78,3 +78,15 @@ class DeviceTestCase(TestCase): }) self.assertTrue(test.is_valid()) self.assertTrue(test.save()) + + def test_cloned_cluster_device_initial_data(self): + test = DeviceForm(initial={ + 'device_type': get_id(DeviceType, 'poweredge-r640'), + 'device_role': get_id(DeviceRole, 'server'), + 'status': DeviceStatusChoices.STATUS_ACTIVE, + 'site': get_id(Site, 'test1'), + "cluster": Cluster.objects.get(id=4).id, + }) + self.assertEqual(test.initial['manufacturer'], get_id(Manufacturer, 'dell')) + self.assertIn('cluster_group', test.initial) + self.assertEqual(test.initial['cluster_group'], get_id(ClusterGroup, 'vm-host')) diff --git a/netbox/virtualization/fixtures/virtualization.json b/netbox/virtualization/fixtures/virtualization.json new file mode 100644 index 000000000..3c9537802 --- /dev/null +++ b/netbox/virtualization/fixtures/virtualization.json @@ -0,0 +1,170 @@ +[ +{ + "model": "virtualization.clustertype", + "pk": 1, + "fields": { + "created": "2016-08-01", + "last_updated": "2016-08-01T15:22:42.289Z", + "name": "Public Cloud", + "slug": "public-cloud" + } +}, +{ + "model": "virtualization.clustertype", + "pk": 2, + "fields": { + "created": "2016-08-01", + "last_updated": "2016-08-01T15:22:42.289Z", + "name": "vSphere", + "slug": "vsphere" + } +}, +{ + "model": "virtualization.clustertype", + "pk": 3, + "fields": { + "created": "2016-08-01", + "last_updated": "2016-08-01T15:22:42.289Z", + "name": "Hyper-V", + "slug": "hyper-v" + } +}, +{ + "model": "virtualization.clustertype", + "pk": 4, + "fields": { + "created": "2016-08-01", + "last_updated": "2016-08-01T15:22:42.289Z", + "name": "libvirt", + "slug": "libvirt" + } +}, +{ + "model": "virtualization.clustertype", + "pk": 5, + "fields": { + "created": "2016-08-01", + "last_updated": "2016-08-01T15:22:42.289Z", + "name": "LXD", + "slug": "lxd" + } +}, +{ + "model": "virtualization.clustertype", + "pk": 6, + "fields": { + "created": "2016-08-01", + "last_updated": "2016-08-01T15:22:42.289Z", + "name": "Docker", + "slug": "docker" + } +}, +{ + "model": "virtualization.clustergroup", + "pk": 1, + "fields": { + "created": "2016-08-01", + "last_updated": "2016-08-01T15:22:42.289Z", + "name": "VM Host", + "slug": "vm-host" + } +}, +{ + "model": "virtualization.cluster", + "pk": 1, + "fields": { + "created": "2016-08-01", + "last_updated": "2016-08-01T15:22:42.289Z", + "name": "Digital Ocean", + "type": 1, + "group": 1, + "tenant": null, + "site": null, + "comments": "" + } +}, +{ + "model": "virtualization.cluster", + "pk": 2, + "fields": { + "created": "2016-08-01", + "last_updated": "2016-08-01T15:22:42.289Z", + "name": "Amazon EC2", + "type": 1, + "group": 1, + "tenant": null, + "site": null, + "comments": "" + } +}, +{ + "model": "virtualization.cluster", + "pk": 3, + "fields": { + "created": "2016-08-01", + "last_updated": "2016-08-01T15:22:42.289Z", + "name": "Microsoft Azure", + "type": 1, + "group": 1, + "tenant": null, + "site": null, + "comments": "" + } +}, +{ + "model": "virtualization.cluster", + "pk": 4, + "fields": { + "created": "2016-08-01", + "last_updated": "2016-08-01T15:22:42.289Z", + "name": "vSphere Cluster", + "type": 2, + "group": 1, + "tenant": null, + "site": null, + "comments": "" + } +}, +{ + "model": "virtualization.virtualmachine", + "pk": 1, + "fields": { + "local_context_data": null, + "created": "2019-12-19", + "last_updated": "2019-12-19T05:24:19.146Z", + "cluster": 2, + "tenant": null, + "platform": null, + "name": "vm1", + "status": "active", + "role": null, + "primary_ip4": null, + "primary_ip6": null, + "vcpus": null, + "memory": null, + "disk": null, + "comments": "" + } +}, +{ + "model": "virtualization.virtualmachine", + "pk": 2, + "fields": { + "local_context_data": null, + "created": "2019-12-19", + "last_updated": "2019-12-19T05:24:41.478Z", + "cluster": 1, + "tenant": null, + "platform": null, + "name": "vm2", + "status": "active", + "role": null, + "primary_ip4": null, + "primary_ip6": null, + "vcpus": null, + "memory": null, + "disk": null, + "comments": "" + } +} +]