Skip to content

Commit

Permalink
Work on #7854
Browse files Browse the repository at this point in the history
  • Loading branch information
DanSheps committed Oct 28, 2022
1 parent 85a4b1f commit cd32863
Show file tree
Hide file tree
Showing 17 changed files with 587 additions and 11 deletions.
16 changes: 16 additions & 0 deletions netbox/dcim/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,22 @@ def get_parent_device(self, obj):
return data


class VirtualDeviceContextSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
device = NestedDeviceSerializer()
tenant = NestedTenantSerializer(required=False, allow_null=True, default=None)
primary_ip = NestedIPAddressSerializer(read_only=True)
primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True)
primary_ip6 = NestedIPAddressSerializer(required=False, allow_null=True)

class Meta:
model = VirtualDeviceContext
fields = [
'id', 'url', 'display', 'name', 'device', 'tenant', 'primary_ip', 'primary_ip4', 'primary_ip6', 'comments',
'tags', 'custom_fields', 'created', 'last_updated',
]


class ModuleSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:module-detail')
device = NestedDeviceSerializer()
Expand Down
1 change: 1 addition & 0 deletions netbox/dcim/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
router.register('device-roles', views.DeviceRoleViewSet)
router.register('platforms', views.PlatformViewSet)
router.register('devices', views.DeviceViewSet)
router.register('vdcs', views.VirtualDeviceContextViewSet)
router.register('modules', views.ModuleViewSet)

# Device components
Expand Down
8 changes: 8 additions & 0 deletions netbox/dcim/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,14 @@ def napalm(self, request, pk):
return Response(response)


class VirtualDeviceContextViewSet(NetBoxModelViewSet):
queryset = VirtualDeviceContext.objects.prefetch_related(
'device__device_type', 'device', 'tenant', 'tags',
)
serializer_class = serializers.VirtualDeviceContextSerializer
filterset_class = filtersets.VirtualDeviceContextFilterSet


class ModuleViewSet(NetBoxModelViewSet):
queryset = Module.objects.prefetch_related(
'device', 'module_bay', 'module_type__manufacturer', 'tags',
Expand Down
71 changes: 71 additions & 0 deletions netbox/dcim/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -1399,3 +1399,74 @@ class PowerFeedPhaseChoices(ChoiceSet):
(PHASE_SINGLE, 'Single phase'),
(PHASE_3PHASE, 'Three-phase'),
)


#
# VDC
#
class VirtualDeviceContextStatusChoices(ChoiceSet):
key = 'VirtualDeviceContext.status'

STATUS_PLANNED = 'planned'
STATUS_ACTIVE = 'active'
STATUS_OFFLINE = 'offline'

CHOICES = [
(STATUS_PLANNED, 'Planned', 'cyan'),
(STATUS_ACTIVE, 'Active', 'green'),
(STATUS_OFFLINE, 'Offline', 'red'),
]


class VirtualDeviceContextTypeChoices(ChoiceSet):

CISCO_NEXUS_VDC = 'cisco-nexus-vdc'
CISCO_ASA_CONTEXT = 'cisco-asa-context'
CISCO_FTD_INSTANCE = 'cisico-ftd-instance'
JUNIPER_VR = 'juniper-virtualrouter'
FORTINET_VDOM = 'fortinet-virtualdomain'
PALOALTO_VSYS = 'paloalto-virtualsystem'
CHECKPOINT_VSYS = 'checkpoint-virtualsystem'

OTHER_VIRTUALCONTEXT = 'other-virtualcontext'

CHOICES = (
(
'Cisco',
(
(CISCO_NEXUS_VDC, 'Nexus VDC'),
(CISCO_ASA_CONTEXT, 'ASA Context'),
(CISCO_FTD_INSTANCE, 'FTD Instance'),
)
),
(
'Juniper',
(
(JUNIPER_VR, 'Virtual Router'),
)
),
(
'Fortinet',
(
(FORTINET_VDOM, 'Virtual Domain'),
)
),
(
'Palo Alto',
(
(PALOALTO_VSYS, 'Virtual System'),
)
),
(
'Checkpoint',
(
(CHECKPOINT_VSYS, 'Virtual System'),
)
),
(
'Other',
(
(OTHER_VIRTUALCONTEXT, 'Virtual Context'),
)
),
)
30 changes: 29 additions & 1 deletion netbox/dcim/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
'SiteFilterSet',
'SiteGroupFilterSet',
'VirtualChassisFilterSet',
'VirtualDeviceContextFilterSet',
)


Expand Down Expand Up @@ -434,6 +435,9 @@ class DeviceTypeFilterSet(NetBoxModelFilterSet):
to_field_name='slug',
label='Manufacturer (slug)',
)
vdc_type = django_filters.MultipleChoiceFilter(
choices=VirtualDeviceContextTypeChoices
)
has_front_image = django_filters.BooleanFilter(
label='Has a front image',
method='_has_front_image'
Expand Down Expand Up @@ -482,7 +486,7 @@ class DeviceTypeFilterSet(NetBoxModelFilterSet):
class Meta:
model = DeviceType
fields = [
'id', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow', 'weight', 'weight_unit'
'id', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow', 'weight', 'weight_unit', 'vdc_type',
]

def search(self, queryset, name, value):
Expand Down Expand Up @@ -1003,6 +1007,30 @@ def _device_bays(self, queryset, name, value):
return queryset.exclude(devicebays__isnull=value)


class VirtualDeviceContextFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
device_id = django_filters.ModelMultipleChoiceFilter(
field_name='device',
queryset=Device.objects.all(),
label='VDC (ID)',
)
device = django_filters.ModelMultipleChoiceFilter(
field_name='device',
queryset=Device.objects.all(),
label='Device model',
)
status = django_filters.MultipleChoiceFilter(
choices=VirtualDeviceContextStatusChoices
)
has_primary_ip = django_filters.BooleanFilter(
method='_has_primary_ip',
label='Has a primary IP',
)

class Meta:
model = VirtualDeviceContext
fields = ['id', 'device', 'name',]


class ModuleFilterSet(NetBoxModelFilterSet):
manufacturer_id = django_filters.ModelMultipleChoiceFilter(
field_name='module_type__manufacturer',
Expand Down
18 changes: 18 additions & 0 deletions netbox/dcim/forms/bulk_edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
'SiteBulkEditForm',
'SiteGroupBulkEditForm',
'VirtualChassisBulkEditForm',
'VirtualDeviceContextBulkEditForm'
)


Expand Down Expand Up @@ -1318,3 +1319,20 @@ class InventoryItemRoleBulkEditForm(NetBoxModelBulkEditForm):
(None, ('color', 'description')),
)
nullable_fields = ('color', 'description')


class VirtualDeviceContextBulkEditForm(NetBoxModelBulkEditForm):
device = DynamicModelChoiceField(
queryset=Device.objects.all(),
required=False
)
status = forms.ChoiceField(
required=False,
choices=add_blank_choice(VirtualDeviceContextStatusChoices),
widget=StaticSelect()
)
model = VirtualDeviceContext
fieldsets = (
(None, ('device',)),
)
nullable_fields = ('device', )
23 changes: 23 additions & 0 deletions netbox/dcim/forms/bulk_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
'SiteCSVForm',
'SiteGroupCSVForm',
'VirtualChassisCSVForm',
'VirtualDeviceContextCSVForm'
)


Expand Down Expand Up @@ -1083,3 +1084,25 @@ def __init__(self, data=None, *args, **kwargs):
f"location__{self.fields['location'].to_field_name}": data.get('location'),
}
self.fields['rack'].queryset = self.fields['rack'].queryset.filter(**params)


class VirtualDeviceContextCSVForm(NetBoxModelCSVForm):

device = CSVModelChoiceField(
queryset=Device.objects.all(),
to_field_name='name',
help_text='Assigned role'
)
tenant = CSVModelChoiceField(
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
help_text='Assigned tenant'
)

class Meta:
fields = [
'name', 'device', 'status', 'tenant', 'identifier', 'comments',
]
model = VirtualDeviceContext
help_texts = {}
38 changes: 37 additions & 1 deletion netbox/dcim/forms/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
'SiteFilterForm',
'SiteGroupFilterForm',
'VirtualChassisFilterForm',
'VirtualDeviceContextFilterForm'
)


Expand Down Expand Up @@ -372,7 +373,7 @@ class DeviceTypeFilterForm(NetBoxModelFilterSetForm):
model = DeviceType
fieldsets = (
(None, ('q', 'tag')),
('Hardware', ('manufacturer_id', 'part_number', 'subdevice_role', 'airflow')),
('Hardware', ('manufacturer_id', 'part_number', 'subdevice_role', 'airflow', 'vdc_type')),
('Images', ('has_front_image', 'has_rear_image')),
('Components', (
'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces',
Expand All @@ -396,6 +397,10 @@ class DeviceTypeFilterForm(NetBoxModelFilterSetForm):
choices=add_blank_choice(DeviceAirflowChoices),
required=False
)
vdc_type = MultipleChoiceField(
choices=add_blank_choice(VirtualDeviceContextTypeChoices),
required=False
)
has_front_image = forms.NullBooleanField(
required=False,
label='Has a front image',
Expand Down Expand Up @@ -728,6 +733,37 @@ class DeviceFilterForm(
tag = TagFilterField(model)


class VirtualDeviceContextFilterForm(
TenancyFilterForm,
NetBoxModelFilterSetForm
):
model = VirtualDeviceContext
fieldsets = (
(None, ('q', 'tag')),
('Hardware', ('device',)),
('Tenant', ('tenant_group_id', 'tenant_id')),
('Miscellaneous', ('has_primary_ip',))
)
device = DynamicModelMultipleChoiceField(
queryset=Device.objects.all(),
required=False,
label=_('Device'),
fetch_trigger='open'
)
status = MultipleChoiceField(
required=False,
choices=add_blank_choice(VirtualDeviceContextStatusChoices)
)
has_primary_ip = forms.NullBooleanField(
required=False,
label='Has a primary IP',
widget=StaticSelect(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
tag = TagFilterField(model)


class ModuleFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, NetBoxModelFilterSetForm):
model = Module
fieldsets = (
Expand Down
Loading

0 comments on commit cd32863

Please sign in to comment.