From a6599874db1e125e9d86fdb3b44565bb9cdee265 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 29 Sep 2017 12:11:20 -0400 Subject: [PATCH] #1493: Extended DeviceRole to include a toggle indicating applicability to virtual machines --- netbox/dcim/api/serializers.py | 2 +- netbox/dcim/forms.py | 2 +- .../migrations/0045_devicerole_vm_role.py | 20 +++++++++++++++++++ netbox/dcim/models.py | 8 +++++++- netbox/dcim/tables.py | 2 +- netbox/virtualization/forms.py | 6 +++--- netbox/virtualization/models.py | 1 + 7 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 netbox/dcim/migrations/0045_devicerole_vm_role.py diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index c08c0f65b..46dfd7682 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -404,7 +404,7 @@ class DeviceRoleSerializer(ValidatedModelSerializer): class Meta: model = DeviceRole - fields = ['id', 'name', 'slug', 'color'] + fields = ['id', 'name', 'slug', 'color', 'vm_role'] class NestedDeviceRoleSerializer(serializers.ModelSerializer): diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index e10b0df56..e4e7a6675 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -531,7 +531,7 @@ class DeviceRoleForm(BootstrapMixin, forms.ModelForm): class Meta: model = DeviceRole - fields = ['name', 'slug', 'color'] + fields = ['name', 'slug', 'color', 'vm_role'] # diff --git a/netbox/dcim/migrations/0045_devicerole_vm_role.py b/netbox/dcim/migrations/0045_devicerole_vm_role.py new file mode 100644 index 000000000..775effaf2 --- /dev/null +++ b/netbox/dcim/migrations/0045_devicerole_vm_role.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2017-09-29 16:09 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0044_virtualization'), + ] + + operations = [ + migrations.AddField( + model_name='devicerole', + name='vm_role', + field=models.BooleanField(default=True, help_text='Virtual machines may be assigned to this role', verbose_name='VM Role'), + ), + ] diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 1fb818f5d..66095a5e8 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -743,11 +743,17 @@ class DeviceBayTemplate(models.Model): class DeviceRole(models.Model): """ Devices are organized by functional role; for example, "Core Switch" or "File Server". Each DeviceRole is assigned a - color to be used when displaying rack elevations. + color to be used when displaying rack elevations. The vm_role field determines whether the role is applicable to + virtual machines as well. """ name = models.CharField(max_length=50, unique=True) slug = models.SlugField(unique=True) color = ColorField() + vm_role = models.BooleanField( + default=True, + verbose_name="VM Role", + help_text="Virtual machines may be assigned to this role" + ) class Meta: ordering = ['name'] diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index a695958d9..1a24035b0 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -369,7 +369,7 @@ class DeviceRoleTable(BaseTable): class Meta(BaseTable.Meta): model = DeviceRole - fields = ('pk', 'name', 'device_count', 'color', 'slug', 'actions') + fields = ('pk', 'name', 'device_count', 'color', 'vm_role', 'slug', 'actions') # diff --git a/netbox/virtualization/forms.py b/netbox/virtualization/forms.py index ef27ea994..fb938ab1f 100644 --- a/netbox/virtualization/forms.py +++ b/netbox/virtualization/forms.py @@ -253,7 +253,7 @@ class VirtualMachineCSVForm(forms.ModelForm): } ) role = forms.ModelChoiceField( - queryset=DeviceRole.objects.all(), + queryset=DeviceRole.objects.filter(vm_role=True), required=False, to_field_name='name', help_text='Name of functional role', @@ -289,7 +289,7 @@ class VirtualMachineBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm): pk = forms.ModelMultipleChoiceField(queryset=VirtualMachine.objects.all(), widget=forms.MultipleHiddenInput) status = forms.ChoiceField(choices=add_blank_choice(STATUS_CHOICES), required=False, initial='') cluster = forms.ModelChoiceField(queryset=Cluster.objects.all(), required=False) - role = forms.ModelChoiceField(queryset=DeviceRole.objects.all(), required=False) + role = forms.ModelChoiceField(queryset=DeviceRole.objects.filter(vm_role=True), required=False) tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), required=False) platform = forms.ModelChoiceField(queryset=Platform.objects.all(), required=False) vcpus = forms.IntegerField(required=False, label='vCPUs') @@ -321,7 +321,7 @@ class VirtualMachineFilterForm(BootstrapMixin, CustomFieldFilterForm): label='Cluster' ) role = FilterChoiceField( - queryset=DeviceRole.objects.annotate(filter_count=Count('virtual_machines')), + queryset=DeviceRole.objects.filter(vm_role=True).annotate(filter_count=Count('virtual_machines')), to_field_name='slug', null_option=(0, 'None') ) diff --git a/netbox/virtualization/models.py b/netbox/virtualization/models.py index 47b179670..8fb13c7cc 100644 --- a/netbox/virtualization/models.py +++ b/netbox/virtualization/models.py @@ -181,6 +181,7 @@ class VirtualMachine(CreatedUpdatedModel, CustomFieldModel): ) role = models.ForeignKey( to='dcim.DeviceRole', + limit_choices_to={'vm_role': True}, on_delete=models.PROTECT, related_name='virtual_machines', blank=True,