Browse Source

Added tenant_group/tenant form section to all objects with tenancy

Jeremy Stretch 8 years ago
parent
commit
473b35f9a3

+ 6 - 2
netbox/circuits/forms.py

@@ -3,6 +3,7 @@ from django.db.models import Count
 
 from dcim.models import Site, Device, Interface, Rack, VIRTUAL_IFACE_TYPES
 from extras.forms import CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
+from tenancy.forms import TenancyForm
 from tenancy.models import Tenant
 from utilities.forms import (
     APISelect, BootstrapMixin, BulkImportForm, ChainedFieldsMixin, ChainedModelChoiceField, CommentField, CSVDataField,
@@ -83,12 +84,15 @@ class CircuitTypeForm(BootstrapMixin, forms.ModelForm):
 # Circuits
 #
 
-class CircuitForm(BootstrapMixin, CustomFieldForm):
+class CircuitForm(BootstrapMixin, TenancyForm, CustomFieldForm):
     comments = CommentField()
 
     class Meta:
         model = Circuit
-        fields = ['cid', 'type', 'provider', 'tenant', 'install_date', 'commit_rate', 'description', 'comments']
+        fields = [
+            'cid', 'type', 'provider', 'install_date', 'commit_rate', 'description', 'tenant_group', 'tenant',
+            'comments',
+        ]
         help_texts = {
             'cid': "Unique circuit ID",
             'install_date': "Format: YYYY-MM-DD",

+ 10 - 9
netbox/dcim/forms.py

@@ -8,6 +8,7 @@ from django.db.models import Count, Q
 
 from extras.forms import CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
 from ipam.models import IPAddress
+from tenancy.forms import TenancyForm
 from tenancy.models import Tenant
 from utilities.forms import (
     APISelect, add_blank_choice, ArrayFieldSelectMultiple, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect,
@@ -81,7 +82,7 @@ class RegionForm(BootstrapMixin, forms.ModelForm):
 # Sites
 #
 
-class SiteForm(BootstrapMixin, CustomFieldForm):
+class SiteForm(BootstrapMixin, TenancyForm, CustomFieldForm):
     region = TreeNodeChoiceField(queryset=Region.objects.all(), required=False)
     slug = SlugField()
     comments = CommentField()
@@ -89,8 +90,8 @@ class SiteForm(BootstrapMixin, CustomFieldForm):
     class Meta:
         model = Site
         fields = [
-            'name', 'slug', 'region', 'tenant', 'facility', 'asn', 'physical_address', 'shipping_address',
-            'contact_name', 'contact_phone', 'contact_email', 'comments',
+            'name', 'slug', 'region', 'tenant_group', 'tenant', 'facility', 'asn', 'physical_address',
+            'shipping_address', 'contact_name', 'contact_phone', 'contact_email', 'comments',
         ]
         widgets = {
             'physical_address': SmallTextarea(attrs={'rows': 3}),
@@ -185,7 +186,7 @@ class RackRoleForm(BootstrapMixin, forms.ModelForm):
 # Racks
 #
 
-class RackForm(BootstrapMixin, ChainedFieldsMixin, CustomFieldForm):
+class RackForm(BootstrapMixin, TenancyForm, CustomFieldForm):
     group = ChainedModelChoiceField(
         queryset=RackGroup.objects.all(),
         chains={'site': 'site'},
@@ -199,8 +200,8 @@ class RackForm(BootstrapMixin, ChainedFieldsMixin, CustomFieldForm):
     class Meta:
         model = Rack
         fields = [
-            'site', 'group', 'name', 'facility_id', 'tenant', 'role', 'type', 'width', 'u_height', 'desc_units',
-            'comments',
+            'site', 'group', 'name', 'facility_id', 'tenant_group', 'tenant', 'role', 'type', 'width', 'u_height',
+            'desc_units', 'comments',
         ]
         help_texts = {
             'site': "The site at which the rack exists",
@@ -534,7 +535,7 @@ class PlatformForm(BootstrapMixin, forms.ModelForm):
 # Devices
 #
 
-class DeviceForm(BootstrapMixin, ChainedFieldsMixin, CustomFieldForm):
+class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldForm):
     site = forms.ModelChoiceField(
         queryset=Site.objects.all(),
         widget=forms.Select(
@@ -580,8 +581,8 @@ class DeviceForm(BootstrapMixin, ChainedFieldsMixin, CustomFieldForm):
     class Meta:
         model = Device
         fields = [
-            'name', 'device_role', 'tenant', 'device_type', 'serial', 'asset_tag', 'site', 'rack', 'position', 'face',
-            'status', 'platform', 'primary_ip4', 'primary_ip6', 'comments',
+            'name', 'device_role', 'device_type', 'serial', 'asset_tag', 'site', 'rack', 'position', 'face', 'status',
+            'platform', 'primary_ip4', 'primary_ip6', 'tenant_group', 'tenant', 'comments',
         ]
         help_texts = {
             'device_role': "The function this device serves",

+ 14 - 10
netbox/ipam/forms.py

@@ -3,10 +3,11 @@ from django.db.models import Count
 
 from dcim.models import Site, Rack, Device, Interface
 from extras.forms import CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
+from tenancy.forms import TenancyForm
 from tenancy.models import Tenant
 from utilities.forms import (
-    APISelect, BootstrapMixin, BulkEditNullBooleanSelect, BulkImportForm, ChainedFieldsMixin, ChainedModelChoiceField,
-    CSVDataField, ExpandableIPAddressField, FilterChoiceField, Livesearch, ReturnURLForm, SlugField, add_blank_choice,
+    APISelect, BootstrapMixin, BulkEditNullBooleanSelect, BulkImportForm, ChainedModelChoiceField, CSVDataField,
+    ExpandableIPAddressField, FilterChoiceField, Livesearch, ReturnURLForm, SlugField, add_blank_choice,
 )
 
 from .models import (
@@ -32,11 +33,11 @@ IPADDRESS_MASK_LENGTH_CHOICES = PREFIX_MASK_LENGTH_CHOICES + [(128, 128)]
 # VRFs
 #
 
-class VRFForm(BootstrapMixin, CustomFieldForm):
+class VRFForm(BootstrapMixin, TenancyForm, CustomFieldForm):
 
     class Meta:
         model = VRF
-        fields = ['name', 'rd', 'tenant', 'enforce_unique', 'description']
+        fields = ['name', 'rd', 'enforce_unique', 'description', 'tenant_group', 'tenant']
         labels = {
             'rd': "RD",
         }
@@ -163,7 +164,7 @@ class RoleForm(BootstrapMixin, forms.ModelForm):
 # Prefixes
 #
 
-class PrefixForm(BootstrapMixin, ChainedFieldsMixin, CustomFieldForm):
+class PrefixForm(BootstrapMixin, TenancyForm, CustomFieldForm):
     site = forms.ModelChoiceField(
         queryset=Site.objects.all(), required=False, label='Site', widget=forms.Select(
             attrs={'filter-for': 'vlan', 'nullable': 'true'}
@@ -177,7 +178,7 @@ class PrefixForm(BootstrapMixin, ChainedFieldsMixin, CustomFieldForm):
 
     class Meta:
         model = Prefix
-        fields = ['prefix', 'vrf', 'tenant', 'site', 'vlan', 'status', 'role', 'is_pool', 'description']
+        fields = ['prefix', 'vrf', 'site', 'vlan', 'status', 'role', 'is_pool', 'description', 'tenant_group', 'tenant']
 
     def __init__(self, *args, **kwargs):
         super(PrefixForm, self).__init__(*args, **kwargs)
@@ -306,7 +307,7 @@ class PrefixFilterForm(BootstrapMixin, CustomFieldFilterForm):
 # IP addresses
 #
 
-class IPAddressForm(BootstrapMixin, ChainedFieldsMixin, ReturnURLForm, CustomFieldForm):
+class IPAddressForm(BootstrapMixin, TenancyForm, ReturnURLForm, CustomFieldForm):
     interface_site = forms.ModelChoiceField(
         queryset=Site.objects.all(),
         required=False,
@@ -399,7 +400,10 @@ class IPAddressForm(BootstrapMixin, ChainedFieldsMixin, ReturnURLForm, CustomFie
 
     class Meta:
         model = IPAddress
-        fields = ['address', 'vrf', 'tenant', 'status', 'description', 'interface', 'primary_for_device', 'nat_inside']
+        fields = [
+            'address', 'vrf', 'status', 'description', 'interface', 'primary_for_device', 'nat_inside', 'tenant_group',
+            'tenant',
+        ]
 
     def __init__(self, instance=None, initial=None, *args, **kwargs):
 
@@ -600,7 +604,7 @@ class VLANGroupFilterForm(BootstrapMixin, forms.Form):
 # VLANs
 #
 
-class VLANForm(BootstrapMixin, ChainedFieldsMixin, CustomFieldForm):
+class VLANForm(BootstrapMixin, TenancyForm, CustomFieldForm):
     site = forms.ModelChoiceField(
         queryset=Site.objects.all(),
         widget=forms.Select(
@@ -619,7 +623,7 @@ class VLANForm(BootstrapMixin, ChainedFieldsMixin, CustomFieldForm):
 
     class Meta:
         model = VLAN
-        fields = ['site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description']
+        fields = ['site', 'group', 'vid', 'name', 'status', 'role', 'description', 'tenant_group', 'tenant']
         help_texts = {
             'site': "Leave blank if this VLAN spans multiple sites",
             'group': "VLAN group (optional)",

+ 7 - 1
netbox/templates/circuits/circuit_edit.html

@@ -8,12 +8,18 @@
             {% render_field form.provider %}
             {% render_field form.cid %}
             {% render_field form.type %}
-            {% render_field form.tenant %}
             {% render_field form.install_date %}
             {% render_field form.commit_rate %}
             {% render_field form.description %}
         </div>
     </div>
+    <div class="panel panel-default">
+        <div class="panel-heading"><strong>Tenancy</strong></div>
+        <div class="panel-body">
+            {% render_field form.tenant_group %}
+            {% render_field form.tenant %}
+        </div>
+    </div>
     {% if form.custom_fields %}
         <div class="panel panel-default">
             <div class="panel-heading"><strong>Custom Fields</strong></div>

+ 7 - 1
netbox/templates/dcim/device_edit.html

@@ -7,7 +7,6 @@
         <div class="panel-body">
             {% render_field form.name %}
             {% render_field form.device_role %}
-            {% render_field form.tenant %}
         </div>
     </div>
     <div class="panel panel-default">
@@ -63,6 +62,13 @@
             {% endif %}
         </div>
     </div>
+    <div class="panel panel-default">
+        <div class="panel-heading"><strong>Tenancy</strong></div>
+        <div class="panel-body">
+            {% render_field form.tenant_group %}
+            {% render_field form.tenant %}
+        </div>
+    </div>
     {% if form.custom_fields %}
         <div class="panel panel-default">
             <div class="panel-heading"><strong>Custom Fields</strong></div>

+ 13 - 2
netbox/templates/dcim/rack_edit.html

@@ -6,11 +6,22 @@
         <div class="panel-heading"><strong>Rack</strong></div>
         <div class="panel-body">
             {% render_field form.site %}
-            {% render_field form.group %}
             {% render_field form.name %}
             {% render_field form.facility_id %}
-            {% render_field form.tenant %}
+            {% render_field form.group %}
             {% render_field form.role %}
+        </div>
+    </div>
+    <div class="panel panel-default">
+        <div class="panel-heading"><strong>Tenancy</strong></div>
+        <div class="panel-body">
+            {% render_field form.tenant_group %}
+            {% render_field form.tenant %}
+        </div>
+    </div>
+    <div class="panel panel-default">
+        <div class="panel-heading"><strong>Dimensions</strong></div>
+        <div class="panel-body">
             {% render_field form.type %}
             {% render_field form.width %}
             {% render_field form.u_height %}

+ 7 - 1
netbox/templates/dcim/site_edit.html

@@ -8,12 +8,18 @@
             {% render_field form.name %}
             {% render_field form.slug %}
             {% render_field form.region %}
-            {% render_field form.tenant %}
             {% render_field form.facility %}
             {% render_field form.asn %}
         </div>
     </div>
     <div class="panel panel-default">
+        <div class="panel-heading"><strong>Tenancy</strong></div>
+        <div class="panel-body">
+            {% render_field form.tenant_group %}
+            {% render_field form.tenant %}
+        </div>
+    </div>
+    <div class="panel panel-default">
         <div class="panel-heading"><strong>Contact Info</strong></div>
         <div class="panel-body">
             {% render_field form.physical_address %}

+ 8 - 2
netbox/templates/ipam/ipaddress_edit.html

@@ -13,13 +13,19 @@
         <div class="panel-heading"><strong>IP Address</strong></div>
         <div class="panel-body">
             {% render_field form.address %}
-            {% render_field form.vrf %}
-            {% render_field form.tenant %}
             {% render_field form.status %}
+            {% render_field form.vrf %}
             {% render_field form.description %}
         </div>
     </div>
     <div class="panel panel-default">
+        <div class="panel-heading"><strong>Tenancy</strong></div>
+        <div class="panel-body">
+            {% render_field form.tenant_group %}
+            {% render_field form.tenant %}
+        </div>
+    </div>
+    <div class="panel panel-default">
         <div class="panel-heading">
             <strong>Interface Assignment</strong>
         </div>

+ 9 - 3
netbox/templates/ipam/prefix_edit.html

@@ -6,14 +6,20 @@
         <div class="panel-heading"><strong>Prefix</strong></div>
         <div class="panel-body">
             {% render_field form.prefix %}
+            {% render_field form.status %}
             {% render_field form.vrf %}
-            {% render_field form.tenant %}
             {% render_field form.site %}
             {% render_field form.vlan %}
-            {% render_field form.status %}
             {% render_field form.role %}
-            {% render_field form.is_pool %}
             {% render_field form.description %}
+            {% render_field form.is_pool %}
+        </div>
+    </div>
+    <div class="panel panel-default">
+        <div class="panel-heading"><strong>Tenancy</strong></div>
+        <div class="panel-body">
+            {% render_field form.tenant_group %}
+            {% render_field form.tenant %}
         </div>
     </div>
     {% if form.custom_fields %}

+ 7 - 1
netbox/templates/ipam/vlan_edit.html

@@ -9,12 +9,18 @@
             {% render_field form.group %}
             {% render_field form.vid %}
             {% render_field form.name %}
-            {% render_field form.tenant %}
             {% render_field form.status %}
             {% render_field form.role %}
             {% render_field form.description %}
         </div>
     </div>
+    <div class="panel panel-default">
+        <div class="panel-heading"><strong>Tenancy</strong></div>
+        <div class="panel-body">
+            {% render_field form.tenant_group %}
+            {% render_field form.tenant %}
+        </div>
+    </div>
     {% if form.custom_fields %}
         <div class="panel panel-default">
             <div class="panel-heading"><strong>Custom Fields</strong></div>

+ 7 - 1
netbox/templates/ipam/vrf_edit.html

@@ -7,11 +7,17 @@
         <div class="panel-body">
             {% render_field form.name %}
             {% render_field form.rd %}
-            {% render_field form.tenant %}
             {% render_field form.enforce_unique %}
             {% render_field form.description %}
         </div>
     </div>
+    <div class="panel panel-default">
+        <div class="panel-heading"><strong>Tenancy</strong></div>
+        <div class="panel-body">
+            {% render_field form.tenant_group %}
+            {% render_field form.tenant %}
+        </div>
+    </div>
     {% if form.custom_fields %}
         <div class="panel panel-default">
             <div class="panel-heading"><strong>Custom Fields</strong></div>

+ 38 - 2
netbox/tenancy/forms.py

@@ -2,8 +2,10 @@ from django import forms
 from django.db.models import Count
 
 from extras.forms import CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
-from utilities.forms import BootstrapMixin, BulkImportForm, CommentField, CSVDataField, FilterChoiceField, SlugField
-
+from utilities.forms import (
+    APISelect, BootstrapMixin, BulkImportForm, ChainedFieldsMixin, ChainedModelChoiceField, CommentField, CSVDataField,
+    FilterChoiceField, SlugField,
+)
 from .models import Tenant, TenantGroup
 
 
@@ -61,3 +63,37 @@ class TenantFilterForm(BootstrapMixin, CustomFieldFilterForm):
         to_field_name='slug',
         null_option=(0, 'None')
     )
+
+
+#
+# Tenancy form extension
+#
+
+class TenancyForm(ChainedFieldsMixin, forms.Form):
+    tenant_group = forms.ModelChoiceField(
+        queryset=TenantGroup.objects.all(),
+        required=False,
+        widget=forms.Select(
+            attrs={'filter-for': 'tenant', 'nullable': 'true'}
+        )
+    )
+    tenant = ChainedModelChoiceField(
+        queryset=Tenant.objects.all(),
+        chains={'group': 'tenant_group'},
+        required=False,
+        widget=APISelect(
+            api_url='/api/tenancy/tenants/?group_id={{tenant_group}}'
+        )
+    )
+
+    def __init__(self, *args, **kwargs):
+
+        # Initialize helper selector
+        instance = kwargs.get('instance')
+        if instance and instance.tenant is not None:
+            try:
+                kwargs['initial']['tenant_group'] = instance.tenant.group
+            except KeyError:
+                kwargs['initial'] = {'tenant_group': instance.tenant.group}
+
+        super(TenancyForm, self).__init__(*args, **kwargs)