diff --git a/docs/models/dcim/platform.md b/docs/models/dcim/platform.md index d080f74a4..cea3efb55 100644 --- a/docs/models/dcim/platform.md +++ b/docs/models/dcim/platform.md @@ -22,6 +22,10 @@ A unique URL-friendly identifier. (This value can be used for filtering.) If designated, this platform will be available for use only to devices assigned to this [manufacturer](./manufacturer.md). This can be handy e.g. for limiting network operating systems to use on hardware produced by the relevant vendor. However, it should not be used when defining general-purpose software platforms. +### Configuration Template + +The default [configuration template](../extras/configtemplate.md) for devices assigned to this platform. + ### NAPALM Driver The [NAPALM driver](https://napalm.readthedocs.io/en/latest/support/index.html) associated with this platform. diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 79b48bf65..38cfc8866 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -620,8 +620,8 @@ class PlatformSerializer(NetBoxModelSerializer): class Meta: model = Platform fields = [ - 'id', 'url', 'display', 'name', 'slug', 'manufacturer', 'napalm_driver', 'napalm_args', 'description', - 'tags', 'custom_fields', 'created', 'last_updated', 'device_count', 'virtualmachine_count', + 'id', 'url', 'display', 'name', 'slug', 'manufacturer', 'config_template', 'napalm_driver', 'napalm_args', + 'description', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count', 'virtualmachine_count', ] diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index 484e983f0..21b05fece 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -379,7 +379,7 @@ class DeviceRoleViewSet(NetBoxModelViewSet): # class PlatformViewSet(NetBoxModelViewSet): - queryset = Platform.objects.prefetch_related('tags').annotate( + queryset = Platform.objects.prefetch_related('config_template', 'tags').annotate( device_count=count_related(Device, 'platform'), virtualmachine_count=count_related(VirtualMachine, 'platform') ) diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index 9e0963fcc..fd3f9425e 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -799,6 +799,10 @@ class PlatformFilterSet(OrganizationalModelFilterSet): to_field_name='slug', label=_('Manufacturer (slug)'), ) + config_template_id = django_filters.ModelMultipleChoiceFilter( + queryset=ConfigTemplate.objects.all(), + label=_('Config template (ID)'), + ) class Meta: model = Platform diff --git a/netbox/dcim/forms/bulk_edit.py b/netbox/dcim/forms/bulk_edit.py index a5d895f66..ea7ab65cd 100644 --- a/netbox/dcim/forms/bulk_edit.py +++ b/netbox/dcim/forms/bulk_edit.py @@ -480,7 +480,10 @@ class PlatformBulkEditForm(NetBoxModelBulkEditForm): max_length=50, required=False ) - # TODO: Bulk edit support for napalm_args + config_template = DynamicModelChoiceField( + queryset=ConfigTemplate.objects.all(), + required=False + ) description = forms.CharField( max_length=200, required=False @@ -488,9 +491,9 @@ class PlatformBulkEditForm(NetBoxModelBulkEditForm): model = Platform fieldsets = ( - (None, ('manufacturer', 'napalm_driver', 'description')), + (None, ('manufacturer', 'config_template', 'napalm_driver', 'description')), ) - nullable_fields = ('manufacturer', 'napalm_driver', 'description') + nullable_fields = ('manufacturer', 'config_template', 'napalm_driver', 'description') class DeviceBulkEditForm(NetBoxModelBulkEditForm): diff --git a/netbox/dcim/forms/bulk_import.py b/netbox/dcim/forms/bulk_import.py index a7a21ba51..e495ec34d 100644 --- a/netbox/dcim/forms/bulk_import.py +++ b/netbox/dcim/forms/bulk_import.py @@ -332,10 +332,18 @@ class PlatformImportForm(NetBoxModelImportForm): to_field_name='name', help_text=_('Limit platform assignments to this manufacturer') ) + config_template = CSVModelChoiceField( + queryset=ConfigTemplate.objects.all(), + to_field_name='name', + required=False, + help_text=_('Config template') + ) class Meta: model = Platform - fields = ('name', 'slug', 'manufacturer', 'napalm_driver', 'napalm_args', 'description', 'tags') + fields = ( + 'name', 'slug', 'manufacturer', 'config_template', 'napalm_driver', 'napalm_args', 'description', 'tags', + ) class BaseDeviceImportForm(NetBoxModelImportForm): diff --git a/netbox/dcim/forms/filtersets.py b/netbox/dcim/forms/filtersets.py index 8eeca7484..4ccc2fe54 100644 --- a/netbox/dcim/forms/filtersets.py +++ b/netbox/dcim/forms/filtersets.py @@ -584,6 +584,11 @@ class PlatformFilterForm(NetBoxModelFilterSetForm): required=False, label=_('Manufacturer') ) + config_template_id = DynamicModelMultipleChoiceField( + queryset=ConfigTemplate.objects.all(), + required=False, + label=_('Config template') + ) tag = TagFilterField(model) diff --git a/netbox/dcim/forms/model_forms.py b/netbox/dcim/forms/model_forms.py index 320a45c91..2e7ca0d4b 100644 --- a/netbox/dcim/forms/model_forms.py +++ b/netbox/dcim/forms/model_forms.py @@ -441,13 +441,17 @@ class PlatformForm(NetBoxModelForm): queryset=Manufacturer.objects.all(), required=False ) + config_template = DynamicModelChoiceField( + queryset=ConfigTemplate.objects.all(), + required=False + ) slug = SlugField( max_length=64 ) fieldsets = ( ('Platform', ( - 'name', 'slug', 'manufacturer', 'napalm_driver', 'napalm_args', 'description', 'tags', + 'name', 'slug', 'manufacturer', 'config_template', 'napalm_driver', 'napalm_args', 'description', 'tags', )), ) @@ -455,7 +459,7 @@ class PlatformForm(NetBoxModelForm): class Meta: model = Platform fields = [ - 'name', 'slug', 'manufacturer', 'napalm_driver', 'napalm_args', 'description', 'tags', + 'name', 'slug', 'manufacturer', 'config_template', 'napalm_driver', 'napalm_args', 'description', 'tags', ] widgets = { 'napalm_args': forms.Textarea(), diff --git a/netbox/dcim/migrations/0170_configtemplate.py b/netbox/dcim/migrations/0170_configtemplate.py index de48ffd37..b1aac0ad2 100644 --- a/netbox/dcim/migrations/0170_configtemplate.py +++ b/netbox/dcim/migrations/0170_configtemplate.py @@ -20,4 +20,9 @@ class Migration(migrations.Migration): name='config_template', field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='device_roles', to='extras.configtemplate'), ), + migrations.AddField( + model_name='platform', + name='config_template', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='platforms', to='extras.configtemplate'), + ), ] diff --git a/netbox/dcim/models/devices.py b/netbox/dcim/models/devices.py index 8b64fc8c5..7ce1a2388 100644 --- a/netbox/dcim/models/devices.py +++ b/netbox/dcim/models/devices.py @@ -436,6 +436,13 @@ class Platform(OrganizationalModel): null=True, help_text=_('Optionally limit this platform to devices of a certain manufacturer') ) + config_template = models.ForeignKey( + to='extras.ConfigTemplate', + on_delete=models.PROTECT, + related_name='platforms', + blank=True, + null=True + ) napalm_driver = models.CharField( max_length=50, blank=True, @@ -880,7 +887,12 @@ class Device(PrimaryModel, ConfigContextModel): """ Return the appropriate ConfigTemplate (if any) for this Device. """ - return self.config_template or self.device_role.config_template + if self.config_template: + return self.config_template + if self.device_role.config_template: + return self.device_role.config_template + if self.platform and self.platform.config_template: + return self.platform.config_template def get_vc_master(self): """ diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index 5aeb64b07..f68960965 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -113,6 +113,9 @@ class PlatformTable(NetBoxTable): manufacturer = tables.Column( linkify=True ) + config_template = tables.Column( + linkify=True + ) device_count = columns.LinkedCountColumn( viewname='dcim:device_list', url_params={'platform_id': 'pk'}, @@ -130,8 +133,8 @@ class PlatformTable(NetBoxTable): class Meta(NetBoxTable.Meta): model = models.Platform fields = ( - 'pk', 'id', 'name', 'manufacturer', 'device_count', 'vm_count', 'slug', 'napalm_driver', 'napalm_args', - 'description', 'tags', 'actions', 'created', 'last_updated', + 'pk', 'id', 'name', 'manufacturer', 'device_count', 'vm_count', 'slug', 'config_template', 'napalm_driver', + 'napalm_args', 'description', 'tags', 'actions', 'created', 'last_updated', ) default_columns = ( 'pk', 'name', 'manufacturer', 'device_count', 'vm_count', 'napalm_driver', 'description', diff --git a/netbox/templates/dcim/platform.html b/netbox/templates/dcim/platform.html index 17a313d82..5123699d4 100644 --- a/netbox/templates/dcim/platform.html +++ b/netbox/templates/dcim/platform.html @@ -39,6 +39,10 @@ Manufacturer {{ object.manufacturer|linkify|placeholder }} + + Config Template + {{ object.config_template|linkify|placeholder }} + NAPALM Driver {{ object.napalm_driver|placeholder }}