mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-23 21:57:47 -06:00
Add tenancy to cluster
fix pep8
This commit is contained in:
@@ -38,6 +38,7 @@ class ClusterGroupSerializer(ValidatedModelSerializer):
|
||||
class ClusterSerializer(TaggitSerializer, CustomFieldModelSerializer):
|
||||
type = NestedClusterTypeSerializer()
|
||||
group = NestedClusterGroupSerializer(required=False, allow_null=True)
|
||||
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
||||
site = NestedSiteSerializer(required=False, allow_null=True)
|
||||
tags = TagListSerializerField(required=False)
|
||||
device_count = serializers.IntegerField(read_only=True)
|
||||
@@ -46,7 +47,7 @@ class ClusterSerializer(TaggitSerializer, CustomFieldModelSerializer):
|
||||
class Meta:
|
||||
model = Cluster
|
||||
fields = [
|
||||
'id', 'name', 'type', 'group', 'site', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
|
||||
'id', 'name', 'type', 'group', 'tenant', 'site', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
|
||||
'device_count', 'virtualmachine_count',
|
||||
]
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class ClusterGroupViewSet(ModelViewSet):
|
||||
|
||||
class ClusterViewSet(CustomFieldModelViewSet):
|
||||
queryset = Cluster.objects.prefetch_related(
|
||||
'type', 'group', 'site', 'tags'
|
||||
'type', 'group', 'tenant', 'site', 'tags'
|
||||
).annotate(
|
||||
device_count=get_subquery(Device, 'cluster'),
|
||||
virtualmachine_count=get_subquery(VirtualMachine, 'cluster')
|
||||
|
||||
@@ -4,6 +4,7 @@ from netaddr import EUI
|
||||
from netaddr.core import AddrFormatError
|
||||
|
||||
from dcim.models import DeviceRole, Interface, Platform, Region, Site
|
||||
from tenancy.models import Tenant
|
||||
from extras.filters import CustomFieldFilterSet
|
||||
from tenancy.filtersets import TenancyFilterSet
|
||||
from utilities.filters import (
|
||||
@@ -56,6 +57,10 @@ class ClusterFilter(CustomFieldFilterSet):
|
||||
to_field_name='slug',
|
||||
label='Cluster type (slug)',
|
||||
)
|
||||
tenant = django_filters.ModelMultipleChoiceFilter(
|
||||
queryset=Tenant.objects.all(),
|
||||
label="Tenant (ID)"
|
||||
)
|
||||
site_id = django_filters.ModelMultipleChoiceFilter(
|
||||
queryset=Site.objects.all(),
|
||||
label='Site (ID)',
|
||||
|
||||
@@ -87,7 +87,7 @@ class ClusterForm(BootstrapMixin, CustomFieldForm):
|
||||
class Meta:
|
||||
model = Cluster
|
||||
fields = [
|
||||
'name', 'type', 'group', 'site', 'comments', 'tags',
|
||||
'name', 'type', 'group', 'tenant', 'site', 'comments', 'tags',
|
||||
]
|
||||
widgets = {
|
||||
'type': APISelect(
|
||||
@@ -129,6 +129,15 @@ class ClusterCSVForm(forms.ModelForm):
|
||||
'invalid_choice': 'Invalid site name.',
|
||||
}
|
||||
)
|
||||
tenant = forms.ModelChoiceField(
|
||||
queryset=Tenant.objects.all(),
|
||||
to_field_name='name',
|
||||
required=False,
|
||||
help_text='Name of assigned tenant',
|
||||
error_messages={
|
||||
'invalid_choice': 'Invalid tenant name'
|
||||
}
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = Cluster
|
||||
@@ -154,6 +163,10 @@ class ClusterBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEdit
|
||||
api_url="/api/virtualization/cluster-groups/"
|
||||
)
|
||||
)
|
||||
tenant = forms.ModelChoiceField(
|
||||
queryset=Tenant.objects.all(),
|
||||
required=False
|
||||
)
|
||||
site = forms.ModelChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
required=False,
|
||||
@@ -167,7 +180,7 @@ class ClusterBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEdit
|
||||
|
||||
class Meta:
|
||||
nullable_fields = [
|
||||
'group', 'site', 'comments',
|
||||
'group', 'site', 'comments', 'tenant',
|
||||
]
|
||||
|
||||
|
||||
@@ -194,6 +207,15 @@ class ClusterFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||
null_option=True,
|
||||
)
|
||||
)
|
||||
tenant = FilterChoiceField(
|
||||
queryset=Tenant.objects.all(),
|
||||
null_label='-- None --',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
api_url="/api/tenancy/tenants/",
|
||||
null_option=True,
|
||||
)
|
||||
)
|
||||
site = FilterChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
to_field_name='slug',
|
||||
|
||||
18
netbox/virtualization/migrations/0010_cluster_add_tenant.py
Normal file
18
netbox/virtualization/migrations/0010_cluster_add_tenant.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tenancy', '0001_initial'),
|
||||
('virtualization', '0009_custom_tag_models'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='cluster',
|
||||
name='tenant',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='clusters', to='tenancy.Tenant'),
|
||||
),
|
||||
]
|
||||
@@ -103,6 +103,13 @@ class Cluster(ChangeLoggedModel, CustomFieldModel):
|
||||
blank=True,
|
||||
null=True
|
||||
)
|
||||
tenant = models.ForeignKey(
|
||||
to='tenancy.Tenant',
|
||||
on_delete=models.PROTECT,
|
||||
related_name='tenants',
|
||||
blank=True,
|
||||
null=True
|
||||
)
|
||||
site = models.ForeignKey(
|
||||
to='dcim.Site',
|
||||
on_delete=models.PROTECT,
|
||||
@@ -150,6 +157,7 @@ class Cluster(ChangeLoggedModel, CustomFieldModel):
|
||||
self.type.name,
|
||||
self.group.name if self.group else None,
|
||||
self.site.name if self.site else None,
|
||||
self.tenant.name if self.tenant else None,
|
||||
self.comments,
|
||||
)
|
||||
|
||||
|
||||
@@ -84,13 +84,14 @@ class ClusterGroupTable(BaseTable):
|
||||
class ClusterTable(BaseTable):
|
||||
pk = ToggleColumn()
|
||||
name = tables.LinkColumn()
|
||||
tenant = tables.LinkColumn('tenancy:tenant', args=[Accessor('tenant.slug')], verbose_name='Tenant')
|
||||
site = tables.LinkColumn('dcim:site', args=[Accessor('site.slug')])
|
||||
device_count = tables.Column(accessor=Accessor('devices.count'), orderable=False, verbose_name='Devices')
|
||||
vm_count = tables.Column(accessor=Accessor('virtual_machines.count'), orderable=False, verbose_name='VMs')
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = Cluster
|
||||
fields = ('pk', 'name', 'type', 'group', 'site', 'device_count', 'vm_count')
|
||||
fields = ('pk', 'name', 'type', 'group', 'tenant', 'site', 'device_count', 'vm_count')
|
||||
|
||||
|
||||
#
|
||||
|
||||
@@ -96,7 +96,7 @@ class ClusterGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class ClusterListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'virtualization.view_cluster'
|
||||
queryset = Cluster.objects.prefetch_related('type', 'group', 'site')
|
||||
queryset = Cluster.objects.prefetch_related('type', 'group', 'site', 'tenant')
|
||||
table = tables.ClusterTable
|
||||
filter = filters.ClusterFilter
|
||||
filter_form = forms.ClusterFilterForm
|
||||
|
||||
Reference in New Issue
Block a user