Ver Fonte

Closes #7120: Add termination_date field to Circuit

jeremystretch há 3 anos atrás
pai
commit
341615668b

+ 1 - 1
docs/models/circuits/circuit.md

@@ -13,7 +13,7 @@ Each circuit is also assigned one of the following operational statuses:
 * Deprovisioning
 * Deprovisioning
 * Decommissioned
 * Decommissioned
 
 
-Circuits also have optional fields for annotating their installation date and commit rate, and may be assigned to NetBox tenants.
+Circuits also have optional fields for annotating their installation and termination dates and commit rate, and may be assigned to NetBox tenants.
 
 
 !!! note
 !!! note
     NetBox currently models only physical circuits: those which have exactly two endpoints. It is common to layer virtualized constructs (_virtual circuits_) such as MPLS or EVPN tunnels on top of these, however NetBox does not yet support virtual circuit modeling.
     NetBox currently models only physical circuits: those which have exactly two endpoints. It is common to layer virtualized constructs (_virtual circuits_) such as MPLS or EVPN tunnels on top of these, however NetBox does not yet support virtual circuit modeling.

+ 3 - 0
docs/release-notes/version-3.3.md

@@ -18,6 +18,7 @@
 * [#1202](https://github.com/netbox-community/netbox/issues/1202) - Support overlapping assignment of NAT IP addresses
 * [#1202](https://github.com/netbox-community/netbox/issues/1202) - Support overlapping assignment of NAT IP addresses
 * [#4350](https://github.com/netbox-community/netbox/issues/4350) - Illustrate reservations vertically alongside rack elevations
 * [#4350](https://github.com/netbox-community/netbox/issues/4350) - Illustrate reservations vertically alongside rack elevations
 * [#5303](https://github.com/netbox-community/netbox/issues/5303) - A virtual machine may be assigned to a site and/or cluster
 * [#5303](https://github.com/netbox-community/netbox/issues/5303) - A virtual machine may be assigned to a site and/or cluster
+* [#7120](https://github.com/netbox-community/netbox/issues/7120) - Add `termination_date` field to Circuit
 * [#7744](https://github.com/netbox-community/netbox/issues/7744) - Add `status` field to Location
 * [#7744](https://github.com/netbox-community/netbox/issues/7744) - Add `status` field to Location
 * [#8222](https://github.com/netbox-community/netbox/issues/8222) - Enable the assignment of a VM to a specific host device within a cluster
 * [#8222](https://github.com/netbox-community/netbox/issues/8222) - Enable the assignment of a VM to a specific host device within a cluster
 * [#8471](https://github.com/netbox-community/netbox/issues/8471) - Add `status` field to Cluster
 * [#8471](https://github.com/netbox-community/netbox/issues/8471) - Add `status` field to Cluster
@@ -32,6 +33,8 @@
 
 
 ### REST API Changes
 ### REST API Changes
 
 
+* circuits.Circuit
+    * Added optional `termination_date` field
 * dcim.Device
 * dcim.Device
     * The `position` field has been changed from an integer to a decimal
     * The `position` field has been changed from an integer to a decimal
 * dcim.DeviceType
 * dcim.DeviceType

+ 3 - 3
netbox/circuits/api/serializers.py

@@ -92,9 +92,9 @@ class CircuitSerializer(NetBoxModelSerializer):
     class Meta:
     class Meta:
         model = Circuit
         model = Circuit
         fields = [
         fields = [
-            'id', 'url', 'display', 'cid', 'provider', 'type', 'status', 'tenant', 'install_date', 'commit_rate',
-            'description', 'termination_a', 'termination_z', 'comments', 'tags', 'custom_fields', 'created',
-            'last_updated',
+            'id', 'url', 'display', 'cid', 'provider', 'type', 'status', 'tenant', 'install_date', 'termination_date',
+            'commit_rate', 'description', 'termination_a', 'termination_z', 'comments', 'tags', 'custom_fields',
+            'created', 'last_updated',
         ]
         ]
 
 
 
 

+ 1 - 1
netbox/circuits/filtersets.py

@@ -183,7 +183,7 @@ class CircuitFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilte
 
 
     class Meta:
     class Meta:
         model = Circuit
         model = Circuit
-        fields = ['id', 'cid', 'description', 'install_date', 'commit_rate']
+        fields = ['id', 'cid', 'description', 'install_date', 'termination_date', 'commit_rate']
 
 
     def search(self, queryset, name, value):
     def search(self, queryset, name, value):
         if not value.strip():
         if not value.strip():

+ 12 - 2
netbox/circuits/forms/bulk_edit.py

@@ -7,7 +7,7 @@ from ipam.models import ASN
 from netbox.forms import NetBoxModelBulkEditForm
 from netbox.forms import NetBoxModelBulkEditForm
 from tenancy.models import Tenant
 from tenancy.models import Tenant
 from utilities.forms import (
 from utilities.forms import (
-    add_blank_choice, CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SmallTextarea,
+    add_blank_choice, CommentField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SmallTextarea,
     StaticSelect,
     StaticSelect,
 )
 )
 
 
@@ -122,6 +122,14 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm):
         queryset=Tenant.objects.all(),
         queryset=Tenant.objects.all(),
         required=False
         required=False
     )
     )
+    install_date = forms.DateField(
+        required=False,
+        widget=DatePicker()
+    )
+    termination_date = forms.DateField(
+        required=False,
+        widget=DatePicker()
+    )
     commit_rate = forms.IntegerField(
     commit_rate = forms.IntegerField(
         required=False,
         required=False,
         label='Commit rate (Kbps)'
         label='Commit rate (Kbps)'
@@ -137,7 +145,9 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm):
 
 
     model = Circuit
     model = Circuit
     fieldsets = (
     fieldsets = (
-        (None, ('type', 'provider', 'status', 'tenant', 'commit_rate', 'description')),
+        ('Circuit', ('provider', 'type', 'status', 'description')),
+        ('Service Parameters', ('install_date', 'termination_date', 'commit_rate')),
+        ('Tenancy', ('tenant',)),
     )
     )
     nullable_fields = (
     nullable_fields = (
         'tenant', 'commit_rate', 'description', 'comments',
         'tenant', 'commit_rate', 'description', 'comments',

+ 2 - 1
netbox/circuits/forms/bulk_import.py

@@ -72,5 +72,6 @@ class CircuitCSVForm(NetBoxModelCSVForm):
     class Meta:
     class Meta:
         model = Circuit
         model = Circuit
         fields = [
         fields = [
-            'cid', 'provider', 'type', 'status', 'tenant', 'install_date', 'commit_rate', 'description', 'comments',
+            'cid', 'provider', 'type', 'status', 'tenant', 'install_date', 'termination_date', 'commit_rate',
+            'description', 'comments',
         ]
         ]

+ 10 - 2
netbox/circuits/forms/filtersets.py

@@ -7,7 +7,7 @@ from dcim.models import Region, Site, SiteGroup
 from ipam.models import ASN
 from ipam.models import ASN
 from netbox.forms import NetBoxModelFilterSetForm
 from netbox.forms import NetBoxModelFilterSetForm
 from tenancy.forms import TenancyFilterForm, ContactModelFilterForm
 from tenancy.forms import TenancyFilterForm, ContactModelFilterForm
-from utilities.forms import DynamicModelMultipleChoiceField, MultipleChoiceField, TagFilterField
+from utilities.forms import DatePicker, DynamicModelMultipleChoiceField, MultipleChoiceField, TagFilterField
 
 
 __all__ = (
 __all__ = (
     'CircuitFilterForm',
     'CircuitFilterForm',
@@ -84,7 +84,7 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
     fieldsets = (
     fieldsets = (
         (None, ('q', 'tag')),
         (None, ('q', 'tag')),
         ('Provider', ('provider_id', 'provider_network_id')),
         ('Provider', ('provider_id', 'provider_network_id')),
-        ('Attributes', ('type_id', 'status', 'commit_rate')),
+        ('Attributes', ('type_id', 'status', 'install_date', 'termination_date', 'commit_rate')),
         ('Location', ('region_id', 'site_group_id', 'site_id')),
         ('Location', ('region_id', 'site_group_id', 'site_id')),
         ('Tenant', ('tenant_group_id', 'tenant_id')),
         ('Tenant', ('tenant_group_id', 'tenant_id')),
         ('Contacts', ('contact', 'contact_role', 'contact_group')),
         ('Contacts', ('contact', 'contact_role', 'contact_group')),
@@ -130,6 +130,14 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
         },
         },
         label=_('Site')
         label=_('Site')
     )
     )
+    install_date = forms.DateField(
+        required=False,
+        widget=DatePicker
+    )
+    termination_date = forms.DateField(
+        required=False,
+        widget=DatePicker
+    )
     commit_rate = forms.IntegerField(
     commit_rate = forms.IntegerField(
         required=False,
         required=False,
         min_value=0,
         min_value=0,

+ 5 - 3
netbox/circuits/forms/models.py

@@ -93,15 +93,16 @@ class CircuitForm(TenancyForm, NetBoxModelForm):
     comments = CommentField()
     comments = CommentField()
 
 
     fieldsets = (
     fieldsets = (
-        ('Circuit', ('provider', 'cid', 'type', 'status', 'install_date', 'commit_rate', 'description', 'tags')),
+        ('Circuit', ('provider', 'cid', 'type', 'status', 'description', 'tags')),
+        ('Service Parameters', ('install_date', 'termination_date', 'commit_rate')),
         ('Tenancy', ('tenant_group', 'tenant')),
         ('Tenancy', ('tenant_group', 'tenant')),
     )
     )
 
 
     class Meta:
     class Meta:
         model = Circuit
         model = Circuit
         fields = [
         fields = [
-            'cid', 'type', 'provider', 'status', 'install_date', 'commit_rate', 'description', 'tenant_group', 'tenant',
-            'comments', 'tags',
+            'cid', 'type', 'provider', 'status', 'install_date', 'termination_date', 'commit_rate', 'description',
+            'tenant_group', 'tenant', 'comments', 'tags',
         ]
         ]
         help_texts = {
         help_texts = {
             'cid': "Unique circuit ID",
             'cid': "Unique circuit ID",
@@ -110,6 +111,7 @@ class CircuitForm(TenancyForm, NetBoxModelForm):
         widgets = {
         widgets = {
             'status': StaticSelect(),
             'status': StaticSelect(),
             'install_date': DatePicker(),
             'install_date': DatePicker(),
+            'termination_date': DatePicker(),
             'commit_rate': SelectSpeedWidget(),
             'commit_rate': SelectSpeedWidget(),
         }
         }
 
 

+ 18 - 0
netbox/circuits/migrations/0036_circuit_termination_date.py

@@ -0,0 +1,18 @@
+# Generated by Django 4.0.5 on 2022-06-22 18:51
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('circuits', '0035_provider_asns'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='circuit',
+            name='termination_date',
+            field=models.DateField(blank=True, null=True),
+        ),
+    ]

+ 7 - 2
netbox/circuits/models/circuits.py

@@ -78,7 +78,12 @@ class Circuit(NetBoxModel):
     install_date = models.DateField(
     install_date = models.DateField(
         blank=True,
         blank=True,
         null=True,
         null=True,
-        verbose_name='Date installed'
+        verbose_name='Installed'
+    )
+    termination_date = models.DateField(
+        blank=True,
+        null=True,
+        verbose_name='Terminates'
     )
     )
     commit_rate = models.PositiveIntegerField(
     commit_rate = models.PositiveIntegerField(
         blank=True,
         blank=True,
@@ -119,7 +124,7 @@ class Circuit(NetBoxModel):
     )
     )
 
 
     clone_fields = [
     clone_fields = [
-        'provider', 'type', 'status', 'tenant', 'install_date', 'commit_rate', 'description',
+        'provider', 'type', 'status', 'tenant', 'install_date', 'termination_date', 'commit_rate', 'description',
     ]
     ]
 
 
     class Meta:
     class Meta:

+ 1 - 1
netbox/circuits/tables/circuits.py

@@ -70,7 +70,7 @@ class CircuitTable(NetBoxTable):
         model = Circuit
         model = Circuit
         fields = (
         fields = (
             'pk', 'id', 'cid', 'provider', 'type', 'status', 'tenant', 'termination_a', 'termination_z', 'install_date',
             'pk', 'id', 'cid', 'provider', 'type', 'status', 'tenant', 'termination_a', 'termination_z', 'install_date',
-            'commit_rate', 'description', 'comments', 'contacts', 'tags', 'created', 'last_updated',
+            'termination_date', 'commit_rate', 'description', 'comments', 'contacts', 'tags', 'created', 'last_updated',
         )
         )
         default_columns = (
         default_columns = (
             'pk', 'cid', 'provider', 'type', 'status', 'tenant', 'termination_a', 'termination_z', 'description',
             'pk', 'cid', 'provider', 'type', 'status', 'tenant', 'termination_a', 'termination_z', 'description',

+ 10 - 6
netbox/circuits/tests/test_filtersets.py

@@ -208,12 +208,12 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
         ProviderNetwork.objects.bulk_create(provider_networks)
         ProviderNetwork.objects.bulk_create(provider_networks)
 
 
         circuits = (
         circuits = (
-            Circuit(provider=providers[0], tenant=tenants[0], type=circuit_types[0], cid='Test Circuit 1', install_date='2020-01-01', commit_rate=1000, status=CircuitStatusChoices.STATUS_ACTIVE, description='foobar1'),
-            Circuit(provider=providers[0], tenant=tenants[0], type=circuit_types[0], cid='Test Circuit 2', install_date='2020-01-02', commit_rate=2000, status=CircuitStatusChoices.STATUS_ACTIVE, description='foobar2'),
-            Circuit(provider=providers[0], tenant=tenants[1], type=circuit_types[0], cid='Test Circuit 3', install_date='2020-01-03', commit_rate=3000, status=CircuitStatusChoices.STATUS_PLANNED),
-            Circuit(provider=providers[1], tenant=tenants[1], type=circuit_types[1], cid='Test Circuit 4', install_date='2020-01-04', commit_rate=4000, status=CircuitStatusChoices.STATUS_PLANNED),
-            Circuit(provider=providers[1], tenant=tenants[2], type=circuit_types[1], cid='Test Circuit 5', install_date='2020-01-05', commit_rate=5000, status=CircuitStatusChoices.STATUS_OFFLINE),
-            Circuit(provider=providers[1], tenant=tenants[2], type=circuit_types[1], cid='Test Circuit 6', install_date='2020-01-06', commit_rate=6000, status=CircuitStatusChoices.STATUS_OFFLINE),
+            Circuit(provider=providers[0], tenant=tenants[0], type=circuit_types[0], cid='Test Circuit 1', install_date='2020-01-01', termination_date='2021-01-01', commit_rate=1000, status=CircuitStatusChoices.STATUS_ACTIVE, description='foobar1'),
+            Circuit(provider=providers[0], tenant=tenants[0], type=circuit_types[0], cid='Test Circuit 2', install_date='2020-01-02', termination_date='2021-01-02', commit_rate=2000, status=CircuitStatusChoices.STATUS_ACTIVE, description='foobar2'),
+            Circuit(provider=providers[0], tenant=tenants[1], type=circuit_types[0], cid='Test Circuit 3', install_date='2020-01-03', termination_date='2021-01-03', commit_rate=3000, status=CircuitStatusChoices.STATUS_PLANNED),
+            Circuit(provider=providers[1], tenant=tenants[1], type=circuit_types[1], cid='Test Circuit 4', install_date='2020-01-04', termination_date='2021-01-04', commit_rate=4000, status=CircuitStatusChoices.STATUS_PLANNED),
+            Circuit(provider=providers[1], tenant=tenants[2], type=circuit_types[1], cid='Test Circuit 5', install_date='2020-01-05', termination_date='2021-01-05', commit_rate=5000, status=CircuitStatusChoices.STATUS_OFFLINE),
+            Circuit(provider=providers[1], tenant=tenants[2], type=circuit_types[1], cid='Test Circuit 6', install_date='2020-01-06', termination_date='2021-01-06', commit_rate=6000, status=CircuitStatusChoices.STATUS_OFFLINE),
         )
         )
         Circuit.objects.bulk_create(circuits)
         Circuit.objects.bulk_create(circuits)
 
 
@@ -235,6 +235,10 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
         params = {'install_date': ['2020-01-01', '2020-01-02']}
         params = {'install_date': ['2020-01-01', '2020-01-02']}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
 
 
+    def test_termination_date(self):
+        params = {'termination_date': ['2021-01-01', '2021-01-02']}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
     def test_commit_rate(self):
     def test_commit_rate(self):
         params = {'commit_rate': ['1000', '2000']}
         params = {'commit_rate': ['1000', '2000']}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)

+ 1 - 0
netbox/circuits/tests/test_views.py

@@ -130,6 +130,7 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase):
             'status': CircuitStatusChoices.STATUS_DECOMMISSIONED,
             'status': CircuitStatusChoices.STATUS_DECOMMISSIONED,
             'tenant': None,
             'tenant': None,
             'install_date': datetime.date(2020, 1, 1),
             'install_date': datetime.date(2020, 1, 1),
+            'termination_date': datetime.date(2021, 1, 1),
             'commit_rate': 1000,
             'commit_rate': 1000,
             'description': 'A new circuit',
             'description': 'A new circuit',
             'comments': 'Some comments',
             'comments': 'Some comments',

+ 4 - 0
netbox/templates/circuits/circuit.html

@@ -45,6 +45,10 @@
                         <th scope="row">Install Date</th>
                         <th scope="row">Install Date</th>
                         <td>{{ object.install_date|annotated_date|placeholder }}</td>
                         <td>{{ object.install_date|annotated_date|placeholder }}</td>
                     </tr>
                     </tr>
+                    <tr>
+                        <th scope="row">Termination Date</th>
+                        <td>{{ object.termination_date|annotated_date|placeholder }}</td>
+                    </tr>
                     <tr>
                     <tr>
                         <th scope="row">Commit Rate</th>
                         <th scope="row">Commit Rate</th>
                         <td>{{ object.commit_rate|humanize_speed|placeholder }}</td>
                         <td>{{ object.commit_rate|humanize_speed|placeholder }}</td>