Skip to content

Commit

Permalink
11969 airflow (netbox-community#16967)
Browse files Browse the repository at this point in the history
* 11960 Add airflow

* 11960 Add airflow

* 11960 fix tests

* 11960 fix racktype form

* 11969 different choices type

* 11969 update docs

* 11969 fix racktype copy

* 11969 fix

* Misc cleanup & reordering of form fields

---------

Co-authored-by: Jeremy Stretch <[email protected]>
  • Loading branch information
arthanson and jeremystretch authored Jul 25, 2024
1 parent 1d6987b commit e62a422
Show file tree
Hide file tree
Showing 18 changed files with 203 additions and 41 deletions.
4 changes: 4 additions & 0 deletions docs/models/dcim/moduletype.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,7 @@ An alternative part number to uniquely identify the module type.
### Weight

The numeric weight of the module, including a unit designation (e.g. 3 kilograms or 1 pound).

### Airflow

The direction in which air circulates through the device chassis for cooling.
3 changes: 3 additions & 0 deletions docs/models/dcim/racktype.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,7 @@ The maximum total weight capacity for all installed devices, inclusive of the ra

If selected, the rack's elevation will display unit 1 at the top of the rack. (Most racks use ascending numbering, with unit 1 assigned to the bottommost position.)

### Airflow

The direction in which air circulates through the rack for cooling.

22 changes: 18 additions & 4 deletions netbox/dcim/api/serializers_/devicetypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,27 @@ class Meta:


class ModuleTypeSerializer(NetBoxModelSerializer):
manufacturer = ManufacturerSerializer(nested=True)
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False, allow_null=True)
manufacturer = ManufacturerSerializer(
nested=True
)
weight_unit = ChoiceField(
choices=WeightUnitChoices,
allow_blank=True,
required=False,
allow_null=True
)
airflow = ChoiceField(
choices=ModuleAirflowChoices,
allow_blank=True,
required=False,
allow_null=True
)

class Meta:
model = ModuleType
fields = [
'id', 'url', 'display_url', 'display', 'manufacturer', 'model', 'part_number', 'weight', 'weight_unit',
'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
'id', 'url', 'display_url', 'display', 'manufacturer', 'model', 'part_number', 'airflow',
'weight', 'weight_unit', 'description', 'comments', 'tags', 'custom_fields',
'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'manufacturer', 'model', 'description')
16 changes: 13 additions & 3 deletions netbox/dcim/api/serializers_/racks.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,19 @@ class RackTypeSerializer(RackBaseSerializer):
manufacturer = ManufacturerSerializer(
nested=True
)
airflow = ChoiceField(
choices=RackAirflowChoices,
allow_blank=True,
required=False
)

class Meta:
model = RackType
fields = [
'id', 'url', 'display_url', 'display', 'manufacturer', 'name', 'slug', 'description', 'form_factor',
'width', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'weight',
'max_weight', 'weight_unit', 'mounting_depth', 'description', 'comments', 'tags', 'custom_fields',
'created', 'last_updated',
'max_weight', 'weight_unit', 'mounting_depth', 'airflow', 'description', 'comments', 'tags',
'custom_fields', 'created', 'last_updated',
]
brief_fields = ('id', 'url', 'display', 'manufacturer', 'name', 'slug', 'description')

Expand All @@ -95,6 +100,11 @@ class RackSerializer(RackBaseSerializer):
choices=RackStatusChoices,
required=False
)
airflow = ChoiceField(
choices=RackAirflowChoices,
allow_blank=True,
required=False
)
role = RackRoleSerializer(
nested=True,
required=False,
Expand Down Expand Up @@ -124,7 +134,7 @@ class Meta:
'id', 'url', 'display_url', 'display', 'name', 'facility_id', 'site', 'location', 'tenant', 'status',
'role', 'serial', 'asset_tag', 'rack_type', 'form_factor', 'width', 'u_height', 'starting_unit', 'weight',
'max_weight', 'weight_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth',
'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count',
'airflow', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count',
'powerfeed_count',
]
brief_fields = ('id', 'url', 'display', 'name', 'description', 'device_count')
Expand Down
30 changes: 30 additions & 0 deletions netbox/dcim/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,17 @@ class RackElevationDetailRenderChoices(ChoiceSet):
)


class RackAirflowChoices(ChoiceSet):

AIRFLOW_FRONT_TO_REAR = 'front-to-rear'
AIRFLOW_REAR_TO_FRONT = 'rear-to-front'

CHOICES = (
(AIRFLOW_FRONT_TO_REAR, _('Front to rear')),
(AIRFLOW_REAR_TO_FRONT, _('Rear to front')),
)


#
# DeviceTypes
#
Expand Down Expand Up @@ -224,6 +235,25 @@ class ModuleStatusChoices(ChoiceSet):
]


class ModuleAirflowChoices(ChoiceSet):

AIRFLOW_FRONT_TO_REAR = 'front-to-rear'
AIRFLOW_REAR_TO_FRONT = 'rear-to-front'
AIRFLOW_LEFT_TO_RIGHT = 'left-to-right'
AIRFLOW_RIGHT_TO_LEFT = 'right-to-left'
AIRFLOW_SIDE_TO_REAR = 'side-to-rear'
AIRFLOW_PASSIVE = 'passive'

CHOICES = (
(AIRFLOW_FRONT_TO_REAR, _('Front to rear')),
(AIRFLOW_REAR_TO_FRONT, _('Rear to front')),
(AIRFLOW_LEFT_TO_RIGHT, _('Left to right')),
(AIRFLOW_RIGHT_TO_LEFT, _('Right to left')),
(AIRFLOW_SIDE_TO_REAR, _('Side to rear')),
(AIRFLOW_PASSIVE, _('Passive')),
)


#
# ConsolePorts
#
Expand Down
7 changes: 4 additions & 3 deletions netbox/dcim/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ class Meta:
model = RackType
fields = (
'id', 'name', 'slug', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit',
'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description',
'mounting_depth', 'airflow', 'weight', 'max_weight', 'weight_unit', 'description',
)

def search(self, queryset, name, value):
Expand Down Expand Up @@ -413,7 +413,8 @@ class Meta:
model = Rack
fields = (
'id', 'name', 'facility_id', 'asset_tag', 'u_height', 'starting_unit', 'desc_units', 'outer_width',
'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description',
'outer_depth', 'outer_unit', 'mounting_depth', 'airflow', 'weight', 'max_weight', 'weight_unit',
'description',
)

def search(self, queryset, name, value):
Expand Down Expand Up @@ -698,7 +699,7 @@ class ModuleTypeFilterSet(NetBoxModelFilterSet):

class Meta:
model = ModuleType
fields = ('id', 'model', 'part_number', 'weight', 'weight_unit', 'description')
fields = ('id', 'model', 'part_number', 'airflow', 'weight', 'weight_unit', 'description')

def search(self, queryset, name, value):
if not value.strip():
Expand Down
27 changes: 22 additions & 5 deletions netbox/dcim/forms/bulk_edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,11 @@ class RackTypeBulkEditForm(NetBoxModelBulkEditForm):
required=False,
min_value=1
)
airflow = forms.ChoiceField(
label=_('Airflow'),
choices=add_blank_choice(RackAirflowChoices),
required=False
)
weight = forms.DecimalField(
label=_('Weight'),
min_value=0,
Expand All @@ -293,10 +298,8 @@ class RackTypeBulkEditForm(NetBoxModelBulkEditForm):

model = RackType
fieldsets = (
FieldSet('manufacturer', 'description', 'form_factor', name=_('Rack Type')),
FieldSet('manufacturer', 'description', 'form_factor', 'width', 'u_height', 'airflow', name=_('Rack Type')),
FieldSet(
'width',
'u_height',
InlineFields('outer_width', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')),
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
'mounting_depth',
Expand Down Expand Up @@ -409,6 +412,11 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
required=False,
min_value=1
)
airflow = forms.ChoiceField(
label=_('Airflow'),
choices=add_blank_choice(RackAirflowChoices),
required=False
)
weight = forms.DecimalField(
label=_('Weight'),
min_value=0,
Expand Down Expand Up @@ -437,7 +445,7 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
FieldSet('status', 'role', 'tenant', 'serial', 'asset_tag', 'description', name=_('Rack')),
FieldSet('region', 'site_group', 'site', 'location', name=_('Location')),
FieldSet(
'form_factor', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit',
'form_factor', 'width', 'u_height', 'desc_units', 'airflow', 'outer_width', 'outer_depth', 'outer_unit',
'mounting_depth', name=_('Hardware')
),
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
Expand Down Expand Up @@ -563,6 +571,11 @@ class ModuleTypeBulkEditForm(NetBoxModelBulkEditForm):
label=_('Part number'),
required=False
)
airflow = forms.ChoiceField(
label=_('Airflow'),
choices=add_blank_choice(ModuleAirflowChoices),
required=False
)
weight = forms.DecimalField(
label=_('Weight'),
min_value=0,
Expand All @@ -584,7 +597,11 @@ class ModuleTypeBulkEditForm(NetBoxModelBulkEditForm):
model = ModuleType
fieldsets = (
FieldSet('manufacturer', 'part_number', 'description', name=_('Module Type')),
FieldSet('weight', 'weight_unit', name=_('Weight')),
FieldSet(
'airflow',
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
name=_('Chassis')
),
)
nullable_fields = ('part_number', 'weight', 'weight_unit', 'description', 'comments')

Expand Down
28 changes: 23 additions & 5 deletions netbox/dcim/forms/bulk_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,12 @@ class RackTypeImportForm(NetBoxModelImportForm):
required=False,
help_text=_('Unit for outer dimensions')
)
airflow = CSVChoiceField(
label=_('Airflow'),
choices=RackAirflowChoices,
required=False,
help_text=_('Airflow direction')
)
weight_unit = CSVChoiceField(
label=_('Weight unit'),
choices=WeightUnitChoices,
Expand All @@ -217,8 +223,8 @@ class Meta:
model = RackType
fields = (
'manufacturer', 'name', 'slug', 'form_factor', 'width', 'u_height', 'starting_unit', 'desc_units',
'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit',
'description', 'comments', 'tags',
'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'airflow', 'weight', 'max_weight',
'weight_unit', 'description', 'comments', 'tags',
)

def __init__(self, data=None, *args, **kwargs):
Expand Down Expand Up @@ -273,6 +279,12 @@ class RackImportForm(NetBoxModelImportForm):
required=False,
help_text=_('Unit for outer dimensions')
)
airflow = CSVChoiceField(
label=_('Airflow'),
choices=RackAirflowChoices,
required=False,
help_text=_('Airflow direction')
)
weight_unit = CSVChoiceField(
label=_('Weight unit'),
choices=WeightUnitChoices,
Expand All @@ -284,8 +296,8 @@ class Meta:
model = Rack
fields = (
'site', 'location', 'name', 'facility_id', 'tenant', 'status', 'role', 'form_factor', 'serial', 'asset_tag',
'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'weight',
'max_weight', 'weight_unit', 'description', 'comments', 'tags',
'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'airflow',
'weight', 'max_weight', 'weight_unit', 'description', 'comments', 'tags',
)

def __init__(self, data=None, *args, **kwargs):
Expand Down Expand Up @@ -400,6 +412,12 @@ class ModuleTypeImportForm(NetBoxModelImportForm):
queryset=Manufacturer.objects.all(),
to_field_name='name'
)
airflow = CSVChoiceField(
label=_('Airflow'),
choices=ModuleAirflowChoices,
required=False,
help_text=_('Airflow direction')
)
weight = forms.DecimalField(
label=_('Weight'),
required=False,
Expand All @@ -414,7 +432,7 @@ class ModuleTypeImportForm(NetBoxModelImportForm):

class Meta:
model = ModuleType
fields = ['manufacturer', 'model', 'part_number', 'description', 'weight', 'weight_unit', 'comments', 'tags']
fields = ['manufacturer', 'model', 'part_number', 'description', 'airflow', 'weight', 'weight_unit', 'comments', 'tags']


class DeviceRoleImportForm(NetBoxModelImportForm):
Expand Down
16 changes: 13 additions & 3 deletions netbox/dcim/forms/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@ class RackBaseFilterForm(NetBoxModelFilterSetForm):
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
airflow = forms.MultipleChoiceField(
label=_('Airflow'),
choices=add_blank_choice(RackAirflowChoices),
required=False
)
weight = forms.DecimalField(
label=_('Weight'),
required=False,
Expand All @@ -288,7 +293,7 @@ class RackTypeFilterForm(RackBaseFilterForm):
model = RackType
fieldsets = (
FieldSet('q', 'filter_id', 'tag'),
FieldSet('form_factor', 'width', 'u_height', name=_('Rack Type')),
FieldSet('form_factor', 'width', 'u_height', 'airflow', name=_('Rack Type')),
FieldSet('starting_unit', 'desc_units', name=_('Numbering')),
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
)
Expand All @@ -308,7 +313,7 @@ class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, RackBaseFilterFo
FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', name=_('Location')),
FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
FieldSet('status', 'role_id', 'serial', 'asset_tag', name=_('Rack')),
FieldSet('form_factor', 'width', 'u_height', name=_('Rack Type')),
FieldSet('form_factor', 'width', 'u_height', 'airflow', name=_('Rack Type')),
FieldSet('starting_unit', 'desc_units', name=_('Numbering')),
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
Expand Down Expand Up @@ -578,7 +583,7 @@ class ModuleTypeFilterForm(NetBoxModelFilterSetForm):
model = ModuleType
fieldsets = (
FieldSet('q', 'filter_id', 'tag'),
FieldSet('manufacturer_id', 'part_number', name=_('Hardware')),
FieldSet('manufacturer_id', 'part_number', 'airflow', name=_('Hardware')),
FieldSet(
'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces',
'pass_through_ports', name=_('Components')
Expand Down Expand Up @@ -638,6 +643,11 @@ class ModuleTypeFilterForm(NetBoxModelFilterSetForm):
)
)
tag = TagFilterField(model)
airflow = forms.MultipleChoiceField(
label=_('Airflow'),
choices=add_blank_choice(ModuleAirflowChoices),
required=False
)
weight = forms.DecimalField(
label=_('Weight'),
required=False
Expand Down
Loading

0 comments on commit e62a422

Please sign in to comment.