From 51a15873bc7652d2de49979aac69d1f83f83a343 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sat, 29 Jul 2023 17:06:01 +0530 Subject: [PATCH] adds tenant on power feed --- netbox/dcim/api/serializers.py | 5 ++++- netbox/dcim/filtersets.py | 2 +- netbox/dcim/forms/bulk_edit.py | 8 ++++++-- netbox/dcim/forms/bulk_import.py | 8 +++++++- netbox/dcim/forms/filtersets.py | 3 ++- netbox/dcim/forms/model_forms.py | 5 +++-- .../dcim/migrations/0180_powerfeed_tenant.py | 20 +++++++++++++++++++ netbox/dcim/models/power.py | 9 ++++++++- netbox/dcim/tables/power.py | 5 ++++- netbox/templates/dcim/powerfeed.html | 9 +++++++++ 10 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 netbox/dcim/migrations/0180_powerfeed_tenant.py diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index a611f64d0..cce69ea31 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -1236,6 +1236,9 @@ class PowerFeedSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect choices=PowerFeedPhaseChoices, default=lambda: PowerFeedPhaseChoices.PHASE_SINGLE, ) + tenant = NestedTenantSerializer( + required=False, + ) class Meta: model = PowerFeed @@ -1243,5 +1246,5 @@ class PowerFeedSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect 'id', 'url', 'display', 'power_panel', 'rack', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization', 'mark_connected', 'cable', 'cable_end', 'link_peers', 'link_peers_type', 'connected_endpoints', 'connected_endpoints_type', 'connected_endpoints_reachable', 'description', - 'comments', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied', + 'tenant', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied', ] diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index 416c022ce..e575c00db 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -1880,7 +1880,7 @@ class PowerPanelFilterSet(NetBoxModelFilterSet, ContactModelFilterSet): return queryset.filter(qs_filter) -class PowerFeedFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet): +class PowerFeedFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet, TenancyFilterSet): region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='power_panel__site__region', diff --git a/netbox/dcim/forms/bulk_edit.py b/netbox/dcim/forms/bulk_edit.py index d721cb09b..9ee938859 100644 --- a/netbox/dcim/forms/bulk_edit.py +++ b/netbox/dcim/forms/bulk_edit.py @@ -754,6 +754,10 @@ class PowerFeedBulkEditForm(NetBoxModelBulkEditForm): required=False, widget=BulkEditNullBooleanSelect ) + tenant = DynamicModelChoiceField( + queryset=Tenant.objects.all(), + required=False + ) description = forms.CharField( max_length=200, required=False @@ -764,10 +768,10 @@ class PowerFeedBulkEditForm(NetBoxModelBulkEditForm): model = PowerFeed fieldsets = ( - (None, ('power_panel', 'rack', 'status', 'type', 'mark_connected', 'description')), + (None, ('power_panel', 'rack', 'status', 'type', 'mark_connected', 'description', 'tenant')), ('Power', ('supply', 'phase', 'voltage', 'amperage', 'max_utilization')) ) - nullable_fields = ('location', 'description', 'comments') + nullable_fields = ('location', 'tenant', 'description', 'comments') # diff --git a/netbox/dcim/forms/bulk_import.py b/netbox/dcim/forms/bulk_import.py index cd774fd18..d3acbc716 100644 --- a/netbox/dcim/forms/bulk_import.py +++ b/netbox/dcim/forms/bulk_import.py @@ -1174,6 +1174,12 @@ class PowerFeedImportForm(NetBoxModelImportForm): required=False, help_text=_('Rack') ) + tenant = CSVModelChoiceField( + queryset=Tenant.objects.all(), + to_field_name='name', + required=False, + help_text=_('Assigned tenant') + ) status = CSVChoiceField( choices=PowerFeedStatusChoices, help_text=_('Operational status') @@ -1195,7 +1201,7 @@ class PowerFeedImportForm(NetBoxModelImportForm): model = PowerFeed fields = ( 'site', 'power_panel', 'location', 'rack', 'name', 'status', 'type', 'mark_connected', 'supply', 'phase', - 'voltage', 'amperage', 'max_utilization', 'description', 'comments', 'tags', + 'voltage', 'amperage', 'max_utilization', 'tenant', 'description', 'comments', 'tags', ) def __init__(self, data=None, *args, **kwargs): diff --git a/netbox/dcim/forms/filtersets.py b/netbox/dcim/forms/filtersets.py index 06d38627d..f0ac017fa 100644 --- a/netbox/dcim/forms/filtersets.py +++ b/netbox/dcim/forms/filtersets.py @@ -985,11 +985,12 @@ class PowerPanelFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm): tag = TagFilterField(model) -class PowerFeedFilterForm(NetBoxModelFilterSetForm): +class PowerFeedFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm): model = PowerFeed fieldsets = ( (None, ('q', 'filter_id', 'tag')), ('Location', ('region_id', 'site_group_id', 'site_id', 'power_panel_id', 'rack_id')), + ('Tenant', ('tenant_group_id', 'tenant_id')), ('Attributes', ('status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization')), ) region_id = DynamicModelMultipleChoiceField( diff --git a/netbox/dcim/forms/model_forms.py b/netbox/dcim/forms/model_forms.py index 632dabb81..4c382babc 100644 --- a/netbox/dcim/forms/model_forms.py +++ b/netbox/dcim/forms/model_forms.py @@ -611,7 +611,7 @@ class PowerPanelForm(NetBoxModelForm): ] -class PowerFeedForm(NetBoxModelForm): +class PowerFeedForm(TenancyForm, NetBoxModelForm): power_panel = DynamicModelChoiceField( queryset=PowerPanel.objects.all(), selector=True @@ -626,13 +626,14 @@ class PowerFeedForm(NetBoxModelForm): fieldsets = ( ('Power Feed', ('power_panel', 'rack', 'name', 'status', 'type', 'description', 'mark_connected', 'tags')), ('Characteristics', ('supply', 'voltage', 'amperage', 'phase', 'max_utilization')), + ('Tenancy', ('tenant_group', 'tenant')), ) class Meta: model = PowerFeed fields = [ 'power_panel', 'rack', 'name', 'status', 'type', 'mark_connected', 'supply', 'phase', 'voltage', 'amperage', - 'max_utilization', 'description', 'comments', 'tags', + 'max_utilization', 'tenant_group', 'tenant', 'description', 'comments', 'tags' ] diff --git a/netbox/dcim/migrations/0180_powerfeed_tenant.py b/netbox/dcim/migrations/0180_powerfeed_tenant.py new file mode 100644 index 000000000..af550b21d --- /dev/null +++ b/netbox/dcim/migrations/0180_powerfeed_tenant.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.8 on 2023-07-29 11:29 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0010_tenant_relax_uniqueness'), + ('dcim', '0179_interfacetemplate_rf_role'), + ] + + operations = [ + migrations.AddField( + model_name='powerfeed', + name='tenant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='power_feeds', to='tenancy.tenant'), + ), + ] diff --git a/netbox/dcim/models/power.py b/netbox/dcim/models/power.py index 3377a9edb..9b6c08527 100644 --- a/netbox/dcim/models/power.py +++ b/netbox/dcim/models/power.py @@ -131,10 +131,17 @@ class PowerFeed(PrimaryModel, PathEndpoint, CabledObjectModel): default=0, editable=False ) + tenant = models.ForeignKey( + to='tenancy.Tenant', + on_delete=models.PROTECT, + related_name='power_feeds', + blank=True, + null=True + ) clone_fields = ( 'power_panel', 'rack', 'status', 'type', 'mark_connected', 'supply', 'phase', 'voltage', 'amperage', - 'max_utilization', + 'max_utilization', 'tenant', ) prerequisite_models = ( 'dcim.PowerPanel', diff --git a/netbox/dcim/tables/power.py b/netbox/dcim/tables/power.py index 272ea2b7d..b7b659079 100644 --- a/netbox/dcim/tables/power.py +++ b/netbox/dcim/tables/power.py @@ -69,6 +69,9 @@ class PowerFeedTable(CableTerminationTable): available_power = tables.Column( verbose_name='Available power (VA)' ) + tenant = tables.Column( + linkify=True + ) comments = columns.MarkdownColumn() tags = columns.TagColumn( url_name='dcim:powerfeed_list' @@ -78,7 +81,7 @@ class PowerFeedTable(CableTerminationTable): model = PowerFeed fields = ( 'pk', 'id', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', - 'max_utilization', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'available_power', + 'max_utilization', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'available_power', 'tenant', 'description', 'comments', 'tags', 'created', 'last_updated', ) default_columns = ( diff --git a/netbox/templates/dcim/powerfeed.html b/netbox/templates/dcim/powerfeed.html index ecfee3a3c..ce00f333c 100644 --- a/netbox/templates/dcim/powerfeed.html +++ b/netbox/templates/dcim/powerfeed.html @@ -43,6 +43,15 @@ {% trans "Description" %} {{ object.description|placeholder }} + + {% trans "Tenant" %} + + {% if object.tenant.group %} + {{ object.tenant.group|linkify }} / + {% endif %} + {{ object.tenant|linkify|placeholder }} + + {% trans "Connected Device" %}