Fixes #19134: Interfaces TX power allows negative value

This commit is contained in:
Adam Smith 2025-04-16 23:58:57 -04:00
parent 248c94bd35
commit 29dd8c0dd4
6 changed files with 34 additions and 7 deletions

View File

@ -1435,7 +1435,7 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
tx_power = forms.IntegerField( tx_power = forms.IntegerField(
required=False, required=False,
label=_('Transmit power (dBm)'), label=_('Transmit power (dBm)'),
min_value=0, min_value=-127,
max_value=127 max_value=127
) )
vrf_id = DynamicModelMultipleChoiceField( vrf_id = DynamicModelMultipleChoiceField(

View File

@ -0,0 +1,21 @@
# Generated by Django 5.1.8 on 2025-04-17 03:36
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dcim', '0200_populate_mac_addresses'),
]
operations = [
migrations.AlterField(
model_name='interface',
name='tx_power',
field=models.SmallIntegerField(blank=True, null=True, validators=[
django.core.validators.MinValueValidator(-127), django.core.validators.MaxValueValidator(127)
]),
),
]

View File

@ -710,10 +710,13 @@ class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEnd
verbose_name=('channel width (MHz)'), verbose_name=('channel width (MHz)'),
help_text=_("Populated by selected channel (if set)") help_text=_("Populated by selected channel (if set)")
) )
tx_power = models.PositiveSmallIntegerField( tx_power = models.SmallIntegerField(
blank=True, blank=True,
null=True, null=True,
validators=(MaxValueValidator(127),), validators=[
MinValueValidator(-127),
MaxValueValidator(127)
],
verbose_name=_('transmit power (dBm)') verbose_name=_('transmit power (dBm)')
) )
poe_mode = models.CharField( poe_mode = models.CharField(

View File

@ -1743,7 +1743,7 @@ class InterfaceTest(Mixins.ComponentTraceMixin, APIViewTestCases.APIViewTestCase
'name': 'Interface 8', 'name': 'Interface 8',
'type': InterfaceTypeChoices.TYPE_80211A, 'type': InterfaceTypeChoices.TYPE_80211A,
'mode': InterfaceModeChoices.MODE_Q_IN_Q, 'mode': InterfaceModeChoices.MODE_Q_IN_Q,
'tx_power': 10, 'tx_power': -10,
'wireless_lans': [wireless_lans[0].pk, wireless_lans[1].pk], 'wireless_lans': [wireless_lans[0].pk, wireless_lans[1].pk],
'rf_channel': "", 'rf_channel': "",
'qinq_svlan': vlans[3].pk, 'qinq_svlan': vlans[3].pk,

View File

@ -4072,7 +4072,7 @@ class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
type=InterfaceTypeChoices.TYPE_OTHER, type=InterfaceTypeChoices.TYPE_OTHER,
enabled=False, enabled=False,
mgmt_only=False, mgmt_only=False,
tx_power=40, tx_power=-40,
mode=InterfaceModeChoices.MODE_Q_IN_Q, mode=InterfaceModeChoices.MODE_Q_IN_Q,
qinq_svlan=vlans[2] qinq_svlan=vlans[2]
), ),
@ -4340,7 +4340,10 @@ class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
def test_tx_power(self): def test_tx_power(self):
params = {'tx_power': [40]} params = {'tx_power': [40]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
params = {'tx_power': [-40]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
def test_vrf(self): def test_vrf(self):
vrfs = VRF.objects.all()[:2] vrfs = VRF.objects.all()[:2]

View File

@ -2660,7 +2660,7 @@ class InterfaceTestCase(ViewTestCases.DeviceComponentViewTestCase):
'poe_mode': InterfacePoEModeChoices.MODE_PD, 'poe_mode': InterfacePoEModeChoices.MODE_PD,
'poe_type': InterfacePoETypeChoices.TYPE_2_8023AT, 'poe_type': InterfacePoETypeChoices.TYPE_2_8023AT,
'mode': InterfaceModeChoices.MODE_TAGGED, 'mode': InterfaceModeChoices.MODE_TAGGED,
'tx_power': 10, 'tx_power': -10,
'untagged_vlan': vlans[0].pk, 'untagged_vlan': vlans[0].pk,
'tagged_vlans': [v.pk for v in vlans[1:4]], 'tagged_vlans': [v.pk for v in vlans[1:4]],
'vrf': vrfs[1].pk, 'vrf': vrfs[1].pk,